jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/ext/jsoncons/extconf.rb +43 -0
  3. data/ext/jsoncons/jsoncons.cpp +161 -0
  4. data/ext/jsoncons/jsoncons.h +10 -0
  5. data/jsoncons.gemspec +44 -0
  6. data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
  7. data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
  8. data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
  9. data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
  10. data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
  11. data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
  12. data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
  13. data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
  14. data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
  15. data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
  16. data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
  17. data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
  18. data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
  19. data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
  20. data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
  21. data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
  22. data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
  23. data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
  24. data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
  25. data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
  26. data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
  27. data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
  28. data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
  29. data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
  30. data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
  31. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
  32. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
  33. data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
  34. data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
  35. data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
  36. data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
  37. data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
  38. data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
  39. data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
  40. data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
  41. data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
  42. data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
  43. data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
  44. data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
  45. data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
  46. data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
  47. data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
  48. data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
  49. data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
  50. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
  51. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
  52. data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
  53. data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
  54. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
  55. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
  56. data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
  57. data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
  58. data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
  59. data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
  60. data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
  61. data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
  62. data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
  63. data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
  64. data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
  65. data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
  66. data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
  67. data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
  68. data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
  69. data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
  70. data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
  71. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
  72. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
  73. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
  74. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
  75. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
  76. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
  77. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
  78. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
  79. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
  80. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
  81. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
  82. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
  83. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
  84. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
  85. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
  86. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
  87. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
  88. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
  89. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
  90. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
  91. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
  92. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
  93. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
  94. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
  95. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
  96. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
  97. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
  98. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
  99. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
  100. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
  101. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
  102. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
  103. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
  104. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
  105. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
  106. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
  107. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
  108. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
  109. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
  110. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
  111. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
  112. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
  113. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
  114. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
  115. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
  116. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
  117. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
  118. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
  119. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
  120. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
  121. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
  122. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
  123. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
  124. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
  125. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
  126. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
  127. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
  128. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
  129. data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
  130. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
  131. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
  132. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
  133. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
  134. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
  135. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
  136. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
  137. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
  138. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
  139. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
  140. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
  141. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
  142. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
  143. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
  144. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
  145. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
  146. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
  147. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
  148. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
  149. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
  150. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
  151. data/lib/jsoncons/version.rb +5 -0
  152. data/lib/jsoncons.rb +33 -0
  153. data/test/jsoncons_test.rb +108 -0
  154. data/test/test_helper.rb +7 -0
  155. metadata +268 -0
@@ -0,0 +1,3329 @@
1
+ // Copyright 2021 Daniel Parker
2
+ // Distributed under the Boost license, Version 1.0.
3
+ // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ // See https://github.com/danielaparker/jsoncons for latest version
6
+
7
+ #ifndef JSONCONS_JSONPATH_EXPRESSION_HPP
8
+ #define JSONCONS_JSONPATH_EXPRESSION_HPP
9
+
10
+ #include <string> // std::basic_string
11
+ #include <vector> // std::vector
12
+ #include <unordered_map> // std::unordered_map
13
+ #include <unordered_set> // std::unordered_set
14
+ #include <limits> // std::numeric_limits
15
+ #include <set> // std::set
16
+ #include <utility> // std::move
17
+ #if defined(JSONCONS_HAS_STD_REGEX)
18
+ #include <regex>
19
+ #endif
20
+ #include <jsoncons/json_type.hpp>
21
+ #include <jsoncons_ext/jsonpath/json_location.hpp>
22
+ #include <jsoncons_ext/jsonpath/jsonpath_error.hpp>
23
+
24
+ namespace jsoncons {
25
+ namespace jsonpath {
26
+
27
+ struct reference_arg_t
28
+ {
29
+ explicit reference_arg_t() = default;
30
+ };
31
+ constexpr reference_arg_t reference_arg{};
32
+
33
+ struct const_reference_arg_t
34
+ {
35
+ explicit const_reference_arg_t() = default;
36
+ };
37
+ constexpr const_reference_arg_t const_reference_arg{};
38
+
39
+ struct literal_arg_t
40
+ {
41
+ explicit literal_arg_t() = default;
42
+ };
43
+ constexpr literal_arg_t literal_arg{};
44
+
45
+ struct end_of_expression_arg_t
46
+ {
47
+ explicit end_of_expression_arg_t() = default;
48
+ };
49
+ constexpr end_of_expression_arg_t end_of_expression_arg{};
50
+
51
+ struct separator_arg_t
52
+ {
53
+ explicit separator_arg_t() = default;
54
+ };
55
+ constexpr separator_arg_t separator_arg{};
56
+
57
+ struct lparen_arg_t
58
+ {
59
+ explicit lparen_arg_t() = default;
60
+ };
61
+ constexpr lparen_arg_t lparen_arg{};
62
+
63
+ struct rparen_arg_t
64
+ {
65
+ explicit rparen_arg_t() = default;
66
+ };
67
+ constexpr rparen_arg_t rparen_arg{};
68
+
69
+ struct begin_union_arg_t
70
+ {
71
+ explicit begin_union_arg_t() = default;
72
+ };
73
+ constexpr begin_union_arg_t begin_union_arg{};
74
+
75
+ struct end_union_arg_t
76
+ {
77
+ explicit end_union_arg_t() = default;
78
+ };
79
+ constexpr end_union_arg_t end_union_arg{};
80
+
81
+ struct begin_filter_arg_t
82
+ {
83
+ explicit begin_filter_arg_t() = default;
84
+ };
85
+ constexpr begin_filter_arg_t begin_filter_arg{};
86
+
87
+ struct end_filter_arg_t
88
+ {
89
+ explicit end_filter_arg_t() = default;
90
+ };
91
+ constexpr end_filter_arg_t end_filter_arg{};
92
+
93
+ struct begin_expression_arg_t
94
+ {
95
+ explicit begin_expression_arg_t() = default;
96
+ };
97
+ constexpr begin_expression_arg_t begin_expression_arg{};
98
+
99
+ struct end_index_expression_arg_t
100
+ {
101
+ explicit end_index_expression_arg_t() = default;
102
+ };
103
+ constexpr end_index_expression_arg_t end_index_expression_arg{};
104
+
105
+ struct end_argument_expression_arg_t
106
+ {
107
+ explicit end_argument_expression_arg_t() = default;
108
+ };
109
+ constexpr end_argument_expression_arg_t end_argument_expression_arg{};
110
+
111
+ struct current_node_arg_t
112
+ {
113
+ explicit current_node_arg_t() = default;
114
+ };
115
+ constexpr current_node_arg_t current_node_arg{};
116
+
117
+ struct root_node_arg_t
118
+ {
119
+ explicit root_node_arg_t() = default;
120
+ };
121
+ constexpr root_node_arg_t root_node_arg{};
122
+
123
+ struct end_function_arg_t
124
+ {
125
+ explicit end_function_arg_t() = default;
126
+ };
127
+ constexpr end_function_arg_t end_function_arg{};
128
+
129
+ struct argument_arg_t
130
+ {
131
+ explicit argument_arg_t() = default;
132
+ };
133
+ constexpr argument_arg_t argument_arg{};
134
+
135
+ enum class result_options {value=0, nodups=1, sort=2, path=4};
136
+
137
+ using result_type = result_options;
138
+
139
+ inline result_options operator~(result_options a)
140
+ {
141
+ return static_cast<result_options>(~static_cast<unsigned int>(a));
142
+ }
143
+
144
+ inline result_options operator&(result_options a, result_options b)
145
+ {
146
+ return static_cast<result_options>(static_cast<unsigned int>(a) & static_cast<unsigned int>(b));
147
+ }
148
+
149
+ inline result_options operator^(result_options a, result_options b)
150
+ {
151
+ return static_cast<result_options>(static_cast<unsigned int>(a) ^ static_cast<unsigned int>(b));
152
+ }
153
+
154
+ inline result_options operator|(result_options a, result_options b)
155
+ {
156
+ return static_cast<result_options>(static_cast<unsigned int>(a) | static_cast<unsigned int>(b));
157
+ }
158
+
159
+ inline result_options operator&=(result_options& a, result_options b)
160
+ {
161
+ a = a & b;
162
+ return a;
163
+ }
164
+
165
+ inline result_options operator^=(result_options& a, result_options b)
166
+ {
167
+ a = a ^ b;
168
+ return a;
169
+ }
170
+
171
+ inline result_options operator|=(result_options& a, result_options b)
172
+ {
173
+ a = a | b;
174
+ return a;
175
+ }
176
+
177
+ template <class Json>
178
+ class parameter;
179
+
180
+ template <class Json,class JsonReference>
181
+ class value_or_pointer
182
+ {
183
+ public:
184
+ friend class parameter<Json>;
185
+ using value_type = Json;
186
+ using reference = JsonReference;
187
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<reference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
188
+ private:
189
+ bool is_value_;
190
+ union
191
+ {
192
+ value_type val_;
193
+ pointer ptr_;
194
+ };
195
+ public:
196
+ value_or_pointer(value_type&& val)
197
+ : is_value_(true), val_(std::move(val))
198
+ {
199
+ }
200
+
201
+ value_or_pointer(pointer ptr)
202
+ : is_value_(false), ptr_(std::move(ptr))
203
+ {
204
+ }
205
+
206
+ value_or_pointer(value_or_pointer&& other) noexcept
207
+ : is_value_(other.is_value_)
208
+ {
209
+ if (is_value_)
210
+ {
211
+ new(&val_)value_type(std::move(other.val_));
212
+ }
213
+ else
214
+ {
215
+ ptr_ = other.ptr_;
216
+ }
217
+ }
218
+
219
+ ~value_or_pointer() noexcept
220
+ {
221
+ if (is_value_)
222
+ {
223
+ val_.~value_type();
224
+ }
225
+ }
226
+
227
+ value_or_pointer& operator=(value_or_pointer&& other) noexcept
228
+ {
229
+ if (is_value_)
230
+ {
231
+ val_.~value_type();
232
+ }
233
+ is_value_ = other.is_value_;
234
+
235
+ if (is_value_)
236
+ {
237
+ new(&val_)value_type(std::move(other.val_));
238
+ }
239
+ else
240
+ {
241
+ ptr_ = other.ptr_;
242
+ }
243
+ return *this;
244
+ }
245
+
246
+ reference value()
247
+ {
248
+ return is_value_ ? val_ : *ptr_;
249
+ }
250
+
251
+ pointer ptr()
252
+ {
253
+ return is_value_ ? &val_ : ptr_;
254
+ }
255
+ };
256
+
257
+ template <class Json>
258
+ class parameter
259
+ {
260
+ using value_type = Json;
261
+ using reference = const Json&;
262
+ using pointer = const Json*;
263
+ private:
264
+ value_or_pointer<Json,reference> data_;
265
+ public:
266
+ template <class JsonReference>
267
+ parameter(value_or_pointer<Json,JsonReference>&& data) noexcept
268
+ : data_(nullptr)
269
+ {
270
+ data_.is_value_ = data.is_value_;
271
+ if (data.is_value_)
272
+ {
273
+ data_.val_ = std::move(data.val_);
274
+ }
275
+ else
276
+ {
277
+ data_.ptr_ = data.ptr_;
278
+ }
279
+ }
280
+
281
+ parameter(parameter&& other) noexcept = default;
282
+
283
+ parameter& operator=(parameter&& other) noexcept = default;
284
+
285
+ const Json& value() const
286
+ {
287
+ return data_.is_value_ ? data_.val_ : *data_.ptr_;
288
+ }
289
+ };
290
+
291
+ template <class Json>
292
+ class custom_function
293
+ {
294
+ public:
295
+ using value_type = Json;
296
+ using char_type = typename Json::char_type;
297
+ using parameter_type = parameter<Json>;
298
+ using function_type = std::function<value_type(jsoncons::span<const parameter_type>, std::error_code& ec)>;
299
+ using string_type = std::basic_string<char_type>;
300
+
301
+ string_type function_name_;
302
+ optional<std::size_t> arity_;
303
+ function_type f_;
304
+
305
+ custom_function(const string_type& function_name,
306
+ const optional<std::size_t>& arity,
307
+ const function_type& f)
308
+ : function_name_(function_name),
309
+ arity_(arity),
310
+ f_(f)
311
+ {
312
+ }
313
+
314
+ custom_function(string_type&& function_name,
315
+ optional<std::size_t>&& arity,
316
+ function_type&& f)
317
+ : function_name_(std::move(function_name)),
318
+ arity_(std::move(arity)),
319
+ f_(std::move(f))
320
+ {
321
+ }
322
+
323
+ custom_function(const custom_function&) = default;
324
+
325
+ custom_function(custom_function&&) = default;
326
+
327
+ const string_type& name() const
328
+ {
329
+ return function_name_;
330
+ }
331
+
332
+ optional<std::size_t> arity() const
333
+ {
334
+ return arity_;
335
+ }
336
+
337
+ const function_type& function() const
338
+ {
339
+ return f_;
340
+ }
341
+ };
342
+
343
+ template <class Json>
344
+ class custom_functions
345
+ {
346
+ using char_type = typename Json::char_type;
347
+ using string_type = std::basic_string<char_type>;
348
+ using value_type = Json;
349
+ using parameter_type = parameter<Json>;
350
+ using function_type = std::function<value_type(jsoncons::span<const parameter_type>, std::error_code& ec)>;
351
+ using const_iterator = typename std::vector<custom_function<Json>>::const_iterator;
352
+
353
+ std::vector<custom_function<Json>> functions_;
354
+ public:
355
+ void register_function(const string_type& name,
356
+ jsoncons::optional<std::size_t> arity,
357
+ const function_type& f)
358
+ {
359
+ functions_.emplace_back(name, arity, f);
360
+ }
361
+
362
+ const_iterator begin() const
363
+ {
364
+ return functions_.begin();
365
+ }
366
+
367
+ const_iterator end() const
368
+ {
369
+ return functions_.end();
370
+ }
371
+ };
372
+
373
+ namespace detail {
374
+
375
+ template <class Json,class JsonReference>
376
+ class dynamic_resources;
377
+
378
+ template <class Json,class JsonReference>
379
+ struct unary_operator
380
+ {
381
+ std::size_t precedence_level_;
382
+ bool is_right_associative_;
383
+
384
+ unary_operator(std::size_t precedence_level,
385
+ bool is_right_associative)
386
+ : precedence_level_(precedence_level),
387
+ is_right_associative_(is_right_associative)
388
+ {
389
+ }
390
+
391
+ virtual ~unary_operator() = default;
392
+
393
+ std::size_t precedence_level() const
394
+ {
395
+ return precedence_level_;
396
+ }
397
+ bool is_right_associative() const
398
+ {
399
+ return is_right_associative_;
400
+ }
401
+
402
+ virtual Json evaluate(JsonReference,
403
+ std::error_code&) const = 0;
404
+ };
405
+
406
+ template <class Json>
407
+ bool is_false(const Json& val)
408
+ {
409
+ return ((val.is_array() && val.empty()) ||
410
+ (val.is_object() && val.empty()) ||
411
+ (val.is_string() && val.as_string_view().empty()) ||
412
+ (val.is_bool() && !val.as_bool()) ||
413
+ val.is_null());
414
+ }
415
+
416
+ template <class Json>
417
+ bool is_true(const Json& val)
418
+ {
419
+ return !is_false(val);
420
+ }
421
+
422
+ template <class Json,class JsonReference>
423
+ class unary_not_operator final : public unary_operator<Json,JsonReference>
424
+ {
425
+ public:
426
+ unary_not_operator()
427
+ : unary_operator<Json,JsonReference>(1, true)
428
+ {}
429
+
430
+ Json evaluate(JsonReference val,
431
+ std::error_code&) const override
432
+ {
433
+ return is_false(val) ? Json(true) : Json(false);
434
+ }
435
+ };
436
+
437
+ template <class Json,class JsonReference>
438
+ class unary_minus_operator final : public unary_operator<Json,JsonReference>
439
+ {
440
+ public:
441
+ unary_minus_operator()
442
+ : unary_operator<Json,JsonReference>(1, true)
443
+ {}
444
+
445
+ Json evaluate(JsonReference val,
446
+ std::error_code&) const override
447
+ {
448
+ if (val.is_int64())
449
+ {
450
+ return Json(-val.template as<int64_t>());
451
+ }
452
+ else if (val.is_double())
453
+ {
454
+ return Json(-val.as_double());
455
+ }
456
+ else
457
+ {
458
+ return Json::null();
459
+ }
460
+ }
461
+ };
462
+
463
+ template <class Json,class JsonReference>
464
+ class regex_operator final : public unary_operator<Json,JsonReference>
465
+ {
466
+ using char_type = typename Json::char_type;
467
+ using string_type = std::basic_string<char_type>;
468
+ std::basic_regex<char_type> pattern_;
469
+ public:
470
+ regex_operator(std::basic_regex<char_type>&& pattern)
471
+ : unary_operator<Json,JsonReference>(2, true),
472
+ pattern_(std::move(pattern))
473
+ {
474
+ }
475
+
476
+ regex_operator(regex_operator&&) = default;
477
+ regex_operator& operator=(regex_operator&&) = default;
478
+
479
+ Json evaluate(JsonReference val,
480
+ std::error_code&) const override
481
+ {
482
+ if (!val.is_string())
483
+ {
484
+ return Json::null();
485
+ }
486
+ return std::regex_search(val.as_string(), pattern_) ? Json(true) : Json(false);
487
+ }
488
+ };
489
+
490
+ template <class Json,class JsonReference>
491
+ struct binary_operator
492
+ {
493
+ std::size_t precedence_level_;
494
+ bool is_right_associative_;
495
+
496
+ binary_operator(std::size_t precedence_level,
497
+ bool is_right_associative = false)
498
+ : precedence_level_(precedence_level),
499
+ is_right_associative_(is_right_associative)
500
+ {
501
+ }
502
+
503
+ std::size_t precedence_level() const
504
+ {
505
+ return precedence_level_;
506
+ }
507
+ bool is_right_associative() const
508
+ {
509
+ return is_right_associative_;
510
+ }
511
+
512
+ virtual Json evaluate(JsonReference,
513
+ JsonReference,
514
+
515
+ std::error_code&) const = 0;
516
+
517
+ virtual std::string to_string(int = 0) const
518
+ {
519
+ return "binary operator";
520
+ }
521
+
522
+ protected:
523
+ ~binary_operator() = default;
524
+ };
525
+
526
+ // Implementations
527
+
528
+ template <class Json,class JsonReference>
529
+ class or_operator final : public binary_operator<Json,JsonReference>
530
+ {
531
+ public:
532
+ or_operator()
533
+ : binary_operator<Json,JsonReference>(9)
534
+ {
535
+ }
536
+
537
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
538
+ {
539
+ if (lhs.is_null() && rhs.is_null())
540
+ {
541
+ return Json::null();
542
+ }
543
+ if (!is_false(lhs))
544
+ {
545
+ return lhs;
546
+ }
547
+ else
548
+ {
549
+ return rhs;
550
+ }
551
+ }
552
+ std::string to_string(int level = 0) const override
553
+ {
554
+ std::string s;
555
+ if (level > 0)
556
+ {
557
+ //s.append("\n");
558
+ s.append(level*2, ' ');
559
+ }
560
+ s.append("or operator");
561
+ return s;
562
+ }
563
+ };
564
+
565
+ template <class Json,class JsonReference>
566
+ class and_operator final : public binary_operator<Json,JsonReference>
567
+ {
568
+ public:
569
+ and_operator()
570
+ : binary_operator<Json,JsonReference>(8)
571
+ {
572
+ }
573
+
574
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
575
+ {
576
+ if (is_true(lhs))
577
+ {
578
+ return rhs;
579
+ }
580
+ else
581
+ {
582
+ return lhs;
583
+ }
584
+ }
585
+
586
+ std::string to_string(int level = 0) const override
587
+ {
588
+ std::string s;
589
+ if (level > 0)
590
+ {
591
+ s.append("\n");
592
+ s.append(level*2, ' ');
593
+ }
594
+ s.append("and operator");
595
+ return s;
596
+ }
597
+ };
598
+
599
+ template <class Json,class JsonReference>
600
+ class eq_operator final : public binary_operator<Json,JsonReference>
601
+ {
602
+ public:
603
+ eq_operator()
604
+ : binary_operator<Json,JsonReference>(6)
605
+ {
606
+ }
607
+
608
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
609
+ {
610
+ return lhs == rhs ? Json(true) : Json(false);
611
+ }
612
+
613
+ std::string to_string(int level = 0) const override
614
+ {
615
+ std::string s;
616
+ if (level > 0)
617
+ {
618
+ s.append("\n");
619
+ s.append(level*2, ' ');
620
+ }
621
+ s.append("equal operator");
622
+ return s;
623
+ }
624
+ };
625
+
626
+ template <class Json,class JsonReference>
627
+ class ne_operator final : public binary_operator<Json,JsonReference>
628
+ {
629
+ public:
630
+ ne_operator()
631
+ : binary_operator<Json,JsonReference>(6)
632
+ {
633
+ }
634
+
635
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
636
+ {
637
+ return lhs != rhs ? Json(true) : Json(false);
638
+ }
639
+
640
+ std::string to_string(int level = 0) const override
641
+ {
642
+ std::string s;
643
+ if (level > 0)
644
+ {
645
+ s.append("\n");
646
+ s.append(level*2, ' ');
647
+ }
648
+ s.append("not equal operator");
649
+ return s;
650
+ }
651
+ };
652
+
653
+ template <class Json,class JsonReference>
654
+ class lt_operator final : public binary_operator<Json,JsonReference>
655
+ {
656
+ public:
657
+ lt_operator()
658
+ : binary_operator<Json,JsonReference>(5)
659
+ {
660
+ }
661
+
662
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
663
+ {
664
+ if (lhs.is_number() && rhs.is_number())
665
+ {
666
+ return lhs < rhs ? Json(true) : Json(false);
667
+ }
668
+ else if (lhs.is_string() && rhs.is_string())
669
+ {
670
+ return lhs < rhs ? Json(true) : Json(false);
671
+ }
672
+ return Json::null();
673
+ }
674
+
675
+ std::string to_string(int level = 0) const override
676
+ {
677
+ std::string s;
678
+ if (level > 0)
679
+ {
680
+ s.append("\n");
681
+ s.append(level*2, ' ');
682
+ }
683
+ s.append("less than operator");
684
+ return s;
685
+ }
686
+ };
687
+
688
+ template <class Json,class JsonReference>
689
+ class lte_operator final : public binary_operator<Json,JsonReference>
690
+ {
691
+ public:
692
+ lte_operator()
693
+ : binary_operator<Json,JsonReference>(5)
694
+ {
695
+ }
696
+
697
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
698
+ {
699
+ if (lhs.is_number() && rhs.is_number())
700
+ {
701
+ return lhs <= rhs ? Json(true) : Json(false);
702
+ }
703
+ else if (lhs.is_string() && rhs.is_string())
704
+ {
705
+ return lhs <= rhs ? Json(true) : Json(false);
706
+ }
707
+ return Json::null();
708
+ }
709
+
710
+ std::string to_string(int level = 0) const override
711
+ {
712
+ std::string s;
713
+ if (level > 0)
714
+ {
715
+ s.append("\n");
716
+ s.append(level*2, ' ');
717
+ }
718
+ s.append("less than or equal operator");
719
+ return s;
720
+ }
721
+ };
722
+
723
+ template <class Json,class JsonReference>
724
+ class gt_operator final : public binary_operator<Json,JsonReference>
725
+ {
726
+ public:
727
+ gt_operator()
728
+ : binary_operator<Json,JsonReference>(5)
729
+ {
730
+ }
731
+
732
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
733
+ {
734
+ //std::cout << "operator> lhs: " << lhs << ", rhs: " << rhs << "\n";
735
+
736
+ if (lhs.is_number() && rhs.is_number())
737
+ {
738
+ return lhs > rhs ? Json(true) : Json(false);
739
+ }
740
+ else if (lhs.is_string() && rhs.is_string())
741
+ {
742
+ return lhs > rhs ? Json(true) : Json(false);
743
+ }
744
+ return Json::null();
745
+ }
746
+
747
+ std::string to_string(int level = 0) const override
748
+ {
749
+ std::string s;
750
+ if (level > 0)
751
+ {
752
+ s.append("\n");
753
+ s.append(level*2, ' ');
754
+ }
755
+ s.append("greater than operator");
756
+ return s;
757
+ }
758
+ };
759
+
760
+ template <class Json,class JsonReference>
761
+ class gte_operator final : public binary_operator<Json,JsonReference>
762
+ {
763
+ public:
764
+ gte_operator()
765
+ : binary_operator<Json,JsonReference>(5)
766
+ {
767
+ }
768
+
769
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
770
+ {
771
+ if (lhs.is_number() && rhs.is_number())
772
+ {
773
+ return lhs >= rhs ? Json(true) : Json(false);
774
+ }
775
+ else if (lhs.is_string() && rhs.is_string())
776
+ {
777
+ return lhs >= rhs ? Json(true) : Json(false);
778
+ }
779
+ return Json::null();
780
+ }
781
+
782
+ std::string to_string(int level = 0) const override
783
+ {
784
+ std::string s;
785
+ if (level > 0)
786
+ {
787
+ s.append("\n");
788
+ s.append(level*2, ' ');
789
+ }
790
+ s.append("greater than or equal operator");
791
+ return s;
792
+ }
793
+ };
794
+
795
+ template <class Json,class JsonReference>
796
+ class plus_operator final : public binary_operator<Json,JsonReference>
797
+ {
798
+ public:
799
+ plus_operator()
800
+ : binary_operator<Json,JsonReference>(4)
801
+ {
802
+ }
803
+
804
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
805
+ {
806
+ if (!(lhs.is_number() && rhs.is_number()))
807
+ {
808
+ return Json::null();
809
+ }
810
+ else if (lhs.is_int64() && rhs.is_int64())
811
+ {
812
+ return Json(((lhs.template as<int64_t>() + rhs.template as<int64_t>())));
813
+ }
814
+ else if (lhs.is_uint64() && rhs.is_uint64())
815
+ {
816
+ return Json((lhs.template as<uint64_t>() + rhs.template as<uint64_t>()));
817
+ }
818
+ else
819
+ {
820
+ return Json((lhs.as_double() + rhs.as_double()));
821
+ }
822
+ }
823
+
824
+ std::string to_string(int level = 0) const override
825
+ {
826
+ std::string s;
827
+ if (level > 0)
828
+ {
829
+ s.append("\n");
830
+ s.append(level*2, ' ');
831
+ }
832
+ s.append("plus operator");
833
+ return s;
834
+ }
835
+ };
836
+
837
+ template <class Json,class JsonReference>
838
+ class minus_operator final : public binary_operator<Json,JsonReference>
839
+ {
840
+ public:
841
+ minus_operator()
842
+ : binary_operator<Json,JsonReference>(4)
843
+ {
844
+ }
845
+
846
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
847
+ {
848
+ if (!(lhs.is_number() && rhs.is_number()))
849
+ {
850
+ return Json::null();
851
+ }
852
+ else if (lhs.is_int64() && rhs.is_int64())
853
+ {
854
+ return Json(((lhs.template as<int64_t>() - rhs.template as<int64_t>())));
855
+ }
856
+ else if (lhs.is_uint64() && rhs.is_uint64())
857
+ {
858
+ return Json((lhs.template as<uint64_t>() - rhs.template as<uint64_t>()));
859
+ }
860
+ else
861
+ {
862
+ return Json((lhs.as_double() - rhs.as_double()));
863
+ }
864
+ }
865
+
866
+ std::string to_string(int level = 0) const override
867
+ {
868
+ std::string s;
869
+ if (level > 0)
870
+ {
871
+ s.append("\n");
872
+ s.append(level*2, ' ');
873
+ }
874
+ s.append("minus operator");
875
+ return s;
876
+ }
877
+ };
878
+
879
+ template <class Json,class JsonReference>
880
+ class mult_operator final : public binary_operator<Json,JsonReference>
881
+ {
882
+ public:
883
+ mult_operator()
884
+ : binary_operator<Json,JsonReference>(3)
885
+ {
886
+ }
887
+
888
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
889
+ {
890
+ if (!(lhs.is_number() && rhs.is_number()))
891
+ {
892
+ return Json::null();
893
+ }
894
+ else if (lhs.is_int64() && rhs.is_int64())
895
+ {
896
+ return Json(((lhs.template as<int64_t>() * rhs.template as<int64_t>())));
897
+ }
898
+ else if (lhs.is_uint64() && rhs.is_uint64())
899
+ {
900
+ return Json((lhs.template as<uint64_t>() * rhs.template as<uint64_t>()));
901
+ }
902
+ else
903
+ {
904
+ return Json((lhs.as_double() * rhs.as_double()));
905
+ }
906
+ }
907
+
908
+ std::string to_string(int level = 0) const override
909
+ {
910
+ std::string s;
911
+ if (level > 0)
912
+ {
913
+ s.append("\n");
914
+ s.append(level*2, ' ');
915
+ }
916
+ s.append("multiply operator");
917
+ return s;
918
+ }
919
+ };
920
+
921
+ template <class Json,class JsonReference>
922
+ class div_operator final : public binary_operator<Json,JsonReference>
923
+ {
924
+ public:
925
+ div_operator()
926
+ : binary_operator<Json,JsonReference>(3)
927
+ {
928
+ }
929
+
930
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
931
+ {
932
+ //std::cout << "operator/ lhs: " << lhs << ", rhs: " << rhs << "\n";
933
+
934
+ if (!(lhs.is_number() && rhs.is_number()))
935
+ {
936
+ return Json::null();
937
+ }
938
+ else if (lhs.is_int64() && rhs.is_int64())
939
+ {
940
+ return Json(((lhs.template as<int64_t>() / rhs.template as<int64_t>())));
941
+ }
942
+ else if (lhs.is_uint64() && rhs.is_uint64())
943
+ {
944
+ return Json((lhs.template as<uint64_t>() / rhs.template as<uint64_t>()));
945
+ }
946
+ else
947
+ {
948
+ return Json((lhs.as_double() / rhs.as_double()));
949
+ }
950
+ }
951
+
952
+ std::string to_string(int level = 0) const override
953
+ {
954
+ std::string s;
955
+ if (level > 0)
956
+ {
957
+ s.append("\n");
958
+ s.append(level*2, ' ');
959
+ }
960
+ s.append("divide operator");
961
+ return s;
962
+ }
963
+ };
964
+
965
+ template <class Json,class JsonReference>
966
+ class modulus_operator final : public binary_operator<Json,JsonReference>
967
+ {
968
+ public:
969
+ modulus_operator()
970
+ : binary_operator<Json,JsonReference>(3)
971
+ {
972
+ }
973
+
974
+ Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
975
+ {
976
+ //std::cout << "operator/ lhs: " << lhs << ", rhs: " << rhs << "\n";
977
+
978
+ if (!(lhs.is_number() && rhs.is_number()))
979
+ {
980
+ return Json::null();
981
+ }
982
+ else if (lhs.is_int64() && rhs.is_int64())
983
+ {
984
+ return Json(((lhs.template as<int64_t>() % rhs.template as<int64_t>())));
985
+ }
986
+ else if (lhs.is_uint64() && rhs.is_uint64())
987
+ {
988
+ return Json((lhs.template as<uint64_t>() % rhs.template as<uint64_t>()));
989
+ }
990
+ else
991
+ {
992
+ return Json(fmod(lhs.as_double(), rhs.as_double()));
993
+ }
994
+ }
995
+
996
+ std::string to_string(int level = 0) const override
997
+ {
998
+ std::string s;
999
+ if (level > 0)
1000
+ {
1001
+ s.append("\n");
1002
+ s.append(level*2, ' ');
1003
+ }
1004
+ s.append("modulus operator");
1005
+ return s;
1006
+ }
1007
+ };
1008
+
1009
+ // function_base
1010
+ template <class Json>
1011
+ class function_base
1012
+ {
1013
+ jsoncons::optional<std::size_t> arg_count_;
1014
+ public:
1015
+ using value_type = Json;
1016
+ using parameter_type = parameter<Json>;
1017
+
1018
+ function_base(jsoncons::optional<std::size_t> arg_count)
1019
+ : arg_count_(arg_count)
1020
+ {
1021
+ }
1022
+
1023
+ virtual ~function_base() noexcept = default;
1024
+
1025
+ jsoncons::optional<std::size_t> arity() const
1026
+ {
1027
+ return arg_count_;
1028
+ }
1029
+
1030
+ virtual value_type evaluate(const std::vector<parameter_type>& args,
1031
+ std::error_code& ec) const = 0;
1032
+
1033
+ virtual std::string to_string(int level = 0) const
1034
+ {
1035
+ std::string s;
1036
+ if (level > 0)
1037
+ {
1038
+ s.append("\n");
1039
+ s.append(level*2, ' ');
1040
+ }
1041
+ s.append("function");
1042
+ return s;
1043
+ }
1044
+ };
1045
+
1046
+ template <class Json>
1047
+ class decorator_function : public function_base<Json>
1048
+ {
1049
+ public:
1050
+ using value_type = Json;
1051
+ using parameter_type = parameter<Json>;
1052
+ using string_view_type = typename Json::string_view_type;
1053
+ using function_type = std::function<value_type(jsoncons::span<const parameter_type>, std::error_code& ec)>;
1054
+ private:
1055
+ function_type f_;
1056
+ public:
1057
+ decorator_function(jsoncons::optional<std::size_t> arity,
1058
+ const function_type& f)
1059
+ : function_base<Json>(arity), f_(f)
1060
+ {
1061
+ }
1062
+
1063
+ value_type evaluate(const std::vector<parameter_type>& args,
1064
+ std::error_code& ec) const override
1065
+ {
1066
+ return f_(args, ec);
1067
+ }
1068
+ };
1069
+
1070
+ template <class Json>
1071
+ class contains_function : public function_base<Json>
1072
+ {
1073
+ public:
1074
+ using value_type = Json;
1075
+ using parameter_type = parameter<Json>;
1076
+ using string_view_type = typename Json::string_view_type;
1077
+
1078
+ contains_function()
1079
+ : function_base<Json>(2)
1080
+ {
1081
+ }
1082
+
1083
+ value_type evaluate(const std::vector<parameter_type>& args,
1084
+ std::error_code& ec) const override
1085
+ {
1086
+ if (args.size() != *this->arity())
1087
+ {
1088
+ ec = jsonpath_errc::invalid_arity;
1089
+ return value_type::null();
1090
+ }
1091
+
1092
+ auto arg0= args[0].value();
1093
+ auto arg1= args[1].value();
1094
+
1095
+ switch (arg0.type())
1096
+ {
1097
+ case json_type::array_value:
1098
+ for (auto& j : arg0.array_range())
1099
+ {
1100
+ if (j == arg1)
1101
+ {
1102
+ return value_type(true);
1103
+ }
1104
+ }
1105
+ return value_type(false);
1106
+ case json_type::string_value:
1107
+ {
1108
+ if (!arg1.is_string())
1109
+ {
1110
+ ec = jsonpath_errc::invalid_type;
1111
+ return value_type::null();
1112
+ }
1113
+ auto sv0 = arg0.template as<string_view_type>();
1114
+ auto sv1 = arg1.template as<string_view_type>();
1115
+ return sv0.find(sv1) != string_view_type::npos ? value_type(true) : value_type(false);
1116
+ }
1117
+ default:
1118
+ {
1119
+ ec = jsonpath_errc::invalid_type;
1120
+ return value_type::null();
1121
+ }
1122
+ }
1123
+ }
1124
+
1125
+ std::string to_string(int level = 0) const override
1126
+ {
1127
+ std::string s;
1128
+ if (level > 0)
1129
+ {
1130
+ s.append("\n");
1131
+ s.append(level*2, ' ');
1132
+ }
1133
+ s.append("contains function");
1134
+ return s;
1135
+ }
1136
+ };
1137
+
1138
+ template <class Json>
1139
+ class ends_with_function : public function_base<Json>
1140
+ {
1141
+ public:
1142
+ using value_type = Json;
1143
+ using parameter_type = parameter<Json>;
1144
+ using string_view_type = typename Json::string_view_type;
1145
+
1146
+ ends_with_function()
1147
+ : function_base<Json>(2)
1148
+ {
1149
+ }
1150
+
1151
+ value_type evaluate(const std::vector<parameter_type>& args,
1152
+ std::error_code& ec) const override
1153
+ {
1154
+ if (args.size() != *this->arity())
1155
+ {
1156
+ ec = jsonpath_errc::invalid_arity;
1157
+ return value_type::null();
1158
+ }
1159
+
1160
+ auto arg0= args[0].value();
1161
+ if (!arg0.is_string())
1162
+ {
1163
+ ec = jsonpath_errc::invalid_type;
1164
+ return value_type::null();
1165
+ }
1166
+
1167
+ auto arg1= args[1].value();
1168
+ if (!arg1.is_string())
1169
+ {
1170
+ ec = jsonpath_errc::invalid_type;
1171
+ return value_type::null();
1172
+ }
1173
+
1174
+ auto sv0 = arg0.template as<string_view_type>();
1175
+ auto sv1 = arg1.template as<string_view_type>();
1176
+
1177
+ if (sv1.length() <= sv0.length() && sv1 == sv0.substr(sv0.length() - sv1.length()))
1178
+ {
1179
+ return value_type(true);
1180
+ }
1181
+ else
1182
+ {
1183
+ return value_type(false);
1184
+ }
1185
+ }
1186
+
1187
+ std::string to_string(int level = 0) const override
1188
+ {
1189
+ std::string s;
1190
+ if (level > 0)
1191
+ {
1192
+ s.append("\n");
1193
+ s.append(level*2, ' ');
1194
+ }
1195
+ s.append("ends_with function");
1196
+ return s;
1197
+ }
1198
+ };
1199
+
1200
+ template <class Json>
1201
+ class starts_with_function : public function_base<Json>
1202
+ {
1203
+ public:
1204
+ using value_type = Json;
1205
+ using parameter_type = parameter<Json>;
1206
+ using string_view_type = typename Json::string_view_type;
1207
+
1208
+ starts_with_function()
1209
+ : function_base<Json>(2)
1210
+ {
1211
+ }
1212
+
1213
+ value_type evaluate(const std::vector<parameter_type>& args,
1214
+ std::error_code& ec) const override
1215
+ {
1216
+ if (args.size() != *this->arity())
1217
+ {
1218
+ ec = jsonpath_errc::invalid_arity;
1219
+ return value_type::null();
1220
+ }
1221
+
1222
+ auto arg0= args[0].value();
1223
+ if (!arg0.is_string())
1224
+ {
1225
+ ec = jsonpath_errc::invalid_type;
1226
+ return value_type::null();
1227
+ }
1228
+
1229
+ auto arg1= args[1].value();
1230
+ if (!arg1.is_string())
1231
+ {
1232
+ ec = jsonpath_errc::invalid_type;
1233
+ return value_type::null();
1234
+ }
1235
+
1236
+ auto sv0 = arg0.template as<string_view_type>();
1237
+ auto sv1 = arg1.template as<string_view_type>();
1238
+
1239
+ if (sv1.length() <= sv0.length() && sv1 == sv0.substr(0, sv1.length()))
1240
+ {
1241
+ return value_type(true);
1242
+ }
1243
+ else
1244
+ {
1245
+ return value_type(false);
1246
+ }
1247
+ }
1248
+
1249
+ std::string to_string(int level = 0) const override
1250
+ {
1251
+ std::string s;
1252
+ if (level > 0)
1253
+ {
1254
+ s.append("\n");
1255
+ s.append(level*2, ' ');
1256
+ }
1257
+ s.append("starts_with function");
1258
+ return s;
1259
+ }
1260
+ };
1261
+
1262
+ template <class Json>
1263
+ class sum_function : public function_base<Json>
1264
+ {
1265
+ public:
1266
+ using value_type = Json;
1267
+ using parameter_type = parameter<Json>;
1268
+
1269
+ sum_function()
1270
+ : function_base<Json>(1)
1271
+ {
1272
+ }
1273
+
1274
+ value_type evaluate(const std::vector<parameter_type>& args,
1275
+ std::error_code& ec) const override
1276
+ {
1277
+ if (args.size() != *this->arity())
1278
+ {
1279
+ ec = jsonpath_errc::invalid_arity;
1280
+ return value_type::null();
1281
+ }
1282
+
1283
+ auto arg0= args[0].value();
1284
+ if (!arg0.is_array())
1285
+ {
1286
+ //std::cout << "arg: " << arg0 << "\n";
1287
+ ec = jsonpath_errc::invalid_type;
1288
+ return value_type::null();
1289
+ }
1290
+ //std::cout << "sum function arg: " << arg0 << "\n";
1291
+
1292
+ double sum = 0;
1293
+ for (auto& j : arg0.array_range())
1294
+ {
1295
+ if (!j.is_number())
1296
+ {
1297
+ ec = jsonpath_errc::invalid_type;
1298
+ return value_type::null();
1299
+ }
1300
+ sum += j.template as<double>();
1301
+ }
1302
+
1303
+ return value_type(sum);
1304
+ }
1305
+
1306
+ std::string to_string(int level = 0) const override
1307
+ {
1308
+ std::string s;
1309
+ if (level > 0)
1310
+ {
1311
+ s.append("\n");
1312
+ s.append(level*2, ' ');
1313
+ }
1314
+ s.append("sum function");
1315
+ return s;
1316
+ }
1317
+ };
1318
+
1319
+ #if defined(JSONCONS_HAS_STD_REGEX)
1320
+
1321
+ template <class Json>
1322
+ class tokenize_function : public function_base<Json>
1323
+ {
1324
+ public:
1325
+ using value_type = Json;
1326
+ using parameter_type = parameter<Json>;
1327
+ using char_type = typename Json::char_type;
1328
+ using string_type = std::basic_string<char_type>;
1329
+
1330
+ tokenize_function()
1331
+ : function_base<Json>(2)
1332
+ {
1333
+ }
1334
+
1335
+ value_type evaluate(const std::vector<parameter_type>& args,
1336
+ std::error_code& ec) const override
1337
+ {
1338
+ if (args.size() != *this->arity())
1339
+ {
1340
+ ec = jsonpath_errc::invalid_arity;
1341
+ return value_type::null();
1342
+ }
1343
+
1344
+ if (!args[0].value().is_string() || !args[1].value().is_string())
1345
+ {
1346
+ //std::cout << "arg: " << arg0 << "\n";
1347
+ ec = jsonpath_errc::invalid_type;
1348
+ return value_type::null();
1349
+ }
1350
+ auto arg0 = args[0].value().template as<string_type>();
1351
+ auto arg1 = args[1].value().template as<string_type>();
1352
+
1353
+ std::regex::flag_type options = std::regex_constants::ECMAScript;
1354
+ std::basic_regex<char_type> pieces_regex(arg1, options);
1355
+
1356
+ std::regex_token_iterator<typename string_type::const_iterator> rit ( arg0.begin(), arg0.end(), pieces_regex, -1);
1357
+ std::regex_token_iterator<typename string_type::const_iterator> rend;
1358
+
1359
+ value_type j(json_array_arg);
1360
+ while (rit != rend)
1361
+ {
1362
+ j.emplace_back(rit->str());
1363
+ ++rit;
1364
+ }
1365
+ return j;
1366
+ }
1367
+
1368
+ std::string to_string(int level = 0) const override
1369
+ {
1370
+ std::string s;
1371
+ if (level > 0)
1372
+ {
1373
+ s.append("\n");
1374
+ s.append(level*2, ' ');
1375
+ }
1376
+ s.append("tokenize function");
1377
+ return s;
1378
+ }
1379
+ };
1380
+
1381
+ #endif // defined(JSONCONS_HAS_STD_REGEX)
1382
+
1383
+ template <class Json>
1384
+ class ceil_function : public function_base<Json>
1385
+ {
1386
+ public:
1387
+ using value_type = Json;
1388
+ using parameter_type = parameter<Json>;
1389
+
1390
+ ceil_function()
1391
+ : function_base<Json>(1)
1392
+ {
1393
+ }
1394
+
1395
+ value_type evaluate(const std::vector<parameter_type>& args,
1396
+ std::error_code& ec) const override
1397
+ {
1398
+ if (args.size() != *this->arity())
1399
+ {
1400
+ ec = jsonpath_errc::invalid_arity;
1401
+ return value_type::null();
1402
+ }
1403
+
1404
+ auto arg0= args[0].value();
1405
+ switch (arg0.type())
1406
+ {
1407
+ case json_type::uint64_value:
1408
+ case json_type::int64_value:
1409
+ {
1410
+ return value_type(arg0.template as<double>());
1411
+ }
1412
+ case json_type::double_value:
1413
+ {
1414
+ return value_type(std::ceil(arg0.template as<double>()));
1415
+ }
1416
+ default:
1417
+ ec = jsonpath_errc::invalid_type;
1418
+ return value_type::null();
1419
+ }
1420
+ }
1421
+
1422
+ std::string to_string(int level = 0) const override
1423
+ {
1424
+ std::string s;
1425
+ if (level > 0)
1426
+ {
1427
+ s.append("\n");
1428
+ s.append(level*2, ' ');
1429
+ }
1430
+ s.append("ceil function");
1431
+ return s;
1432
+ }
1433
+ };
1434
+
1435
+ template <class Json>
1436
+ class floor_function : public function_base<Json>
1437
+ {
1438
+ public:
1439
+ using value_type = Json;
1440
+ using parameter_type = parameter<Json>;
1441
+
1442
+ floor_function()
1443
+ : function_base<Json>(1)
1444
+ {
1445
+ }
1446
+
1447
+ value_type evaluate(const std::vector<parameter_type>& args,
1448
+ std::error_code& ec) const override
1449
+ {
1450
+ if (args.size() != *this->arity())
1451
+ {
1452
+ ec = jsonpath_errc::invalid_arity;
1453
+ return value_type::null();
1454
+ }
1455
+
1456
+ auto arg0= args[0].value();
1457
+ switch (arg0.type())
1458
+ {
1459
+ case json_type::uint64_value:
1460
+ case json_type::int64_value:
1461
+ {
1462
+ return value_type(arg0.template as<double>());
1463
+ }
1464
+ case json_type::double_value:
1465
+ {
1466
+ return value_type(std::floor(arg0.template as<double>()));
1467
+ }
1468
+ default:
1469
+ ec = jsonpath_errc::invalid_type;
1470
+ return value_type::null();
1471
+ }
1472
+ }
1473
+
1474
+ std::string to_string(int level = 0) const override
1475
+ {
1476
+ std::string s;
1477
+ if (level > 0)
1478
+ {
1479
+ s.append("\n");
1480
+ s.append(level*2, ' ');
1481
+ }
1482
+ s.append("floor function");
1483
+ return s;
1484
+ }
1485
+ };
1486
+
1487
+ template <class Json>
1488
+ class to_number_function : public function_base<Json>
1489
+ {
1490
+ public:
1491
+ using value_type = Json;
1492
+ using parameter_type = parameter<Json>;
1493
+
1494
+ to_number_function()
1495
+ : function_base<Json>(1)
1496
+ {
1497
+ }
1498
+
1499
+ value_type evaluate(const std::vector<parameter_type>& args,
1500
+ std::error_code& ec) const override
1501
+ {
1502
+ if (args.size() != *this->arity())
1503
+ {
1504
+ ec = jsonpath_errc::invalid_arity;
1505
+ return value_type::null();
1506
+ }
1507
+
1508
+ auto arg0= args[0].value();
1509
+ switch (arg0.type())
1510
+ {
1511
+ case json_type::int64_value:
1512
+ case json_type::uint64_value:
1513
+ case json_type::double_value:
1514
+ return arg0;
1515
+ case json_type::string_value:
1516
+ {
1517
+ auto sv = arg0.as_string_view();
1518
+ uint64_t un{0};
1519
+ auto result1 = jsoncons::detail::to_integer(sv.data(), sv.length(), un);
1520
+ if (result1)
1521
+ {
1522
+ return value_type(un);
1523
+ }
1524
+ int64_t sn{0};
1525
+ auto result2 = jsoncons::detail::to_integer(sv.data(), sv.length(), sn);
1526
+ if (result2)
1527
+ {
1528
+ return value_type(sn);
1529
+ }
1530
+ jsoncons::detail::chars_to to_double;
1531
+ try
1532
+ {
1533
+ auto s = arg0.as_string();
1534
+ double d = to_double(s.c_str(), s.length());
1535
+ return value_type(d);
1536
+ }
1537
+ catch (const std::exception&)
1538
+ {
1539
+ return value_type::null();
1540
+ }
1541
+ }
1542
+ default:
1543
+ ec = jsonpath_errc::invalid_type;
1544
+ return value_type::null();
1545
+ }
1546
+ }
1547
+
1548
+ std::string to_string(int level = 0) const override
1549
+ {
1550
+ std::string s;
1551
+ if (level > 0)
1552
+ {
1553
+ s.append("\n");
1554
+ s.append(level*2, ' ');
1555
+ }
1556
+ s.append("to_number function");
1557
+ return s;
1558
+ }
1559
+ };
1560
+
1561
+ template <class Json>
1562
+ class prod_function : public function_base<Json>
1563
+ {
1564
+ public:
1565
+ using value_type = Json;
1566
+ using parameter_type = parameter<Json>;
1567
+
1568
+ prod_function()
1569
+ : function_base<Json>(1)
1570
+ {
1571
+ }
1572
+
1573
+ value_type evaluate(const std::vector<parameter_type>& args,
1574
+ std::error_code& ec) const override
1575
+ {
1576
+ if (args.size() != *this->arity())
1577
+ {
1578
+ ec = jsonpath_errc::invalid_arity;
1579
+ return value_type::null();
1580
+ }
1581
+
1582
+ auto arg0= args[0].value();
1583
+ if (!arg0.is_array() || arg0.empty())
1584
+ {
1585
+ //std::cout << "arg: " << arg0 << "\n";
1586
+ ec = jsonpath_errc::invalid_type;
1587
+ return value_type::null();
1588
+ }
1589
+ double prod = 1;
1590
+ for (auto& j : arg0.array_range())
1591
+ {
1592
+ if (!j.is_number())
1593
+ {
1594
+ ec = jsonpath_errc::invalid_type;
1595
+ return value_type::null();
1596
+ }
1597
+ prod *= j.template as<double>();
1598
+ }
1599
+
1600
+ return value_type(prod);
1601
+ }
1602
+
1603
+ std::string to_string(int level = 0) const override
1604
+ {
1605
+ std::string s;
1606
+ if (level > 0)
1607
+ {
1608
+ s.append("\n");
1609
+ s.append(level*2, ' ');
1610
+ }
1611
+ s.append("prod function");
1612
+ return s;
1613
+ }
1614
+ };
1615
+
1616
+ template <class Json>
1617
+ class avg_function : public function_base<Json>
1618
+ {
1619
+ public:
1620
+ using value_type = Json;
1621
+ using parameter_type = parameter<Json>;
1622
+
1623
+ avg_function()
1624
+ : function_base<Json>(1)
1625
+ {
1626
+ }
1627
+
1628
+ value_type evaluate(const std::vector<parameter_type>& args,
1629
+ std::error_code& ec) const override
1630
+ {
1631
+ if (args.size() != *this->arity())
1632
+ {
1633
+ ec = jsonpath_errc::invalid_arity;
1634
+ return value_type::null();
1635
+ }
1636
+
1637
+ auto arg0= args[0].value();
1638
+ if (!arg0.is_array())
1639
+ {
1640
+ ec = jsonpath_errc::invalid_type;
1641
+ return value_type::null();
1642
+ }
1643
+ if (arg0.empty())
1644
+ {
1645
+ return value_type::null();
1646
+ }
1647
+ double sum = 0;
1648
+ for (auto& j : arg0.array_range())
1649
+ {
1650
+ if (!j.is_number())
1651
+ {
1652
+ ec = jsonpath_errc::invalid_type;
1653
+ return value_type::null();
1654
+ }
1655
+ sum += j.template as<double>();
1656
+ }
1657
+
1658
+ return value_type(sum / static_cast<double>(arg0.size()));
1659
+ }
1660
+
1661
+ std::string to_string(int level = 0) const override
1662
+ {
1663
+ std::string s;
1664
+ if (level > 0)
1665
+ {
1666
+ s.append("\n");
1667
+ s.append(level*2, ' ');
1668
+ }
1669
+ s.append("to_string function");
1670
+ return s;
1671
+ }
1672
+ };
1673
+
1674
+ template <class Json>
1675
+ class min_function : public function_base<Json>
1676
+ {
1677
+ public:
1678
+ using value_type = Json;
1679
+ using parameter_type = parameter<Json>;
1680
+
1681
+ min_function()
1682
+ : function_base<Json>(1)
1683
+ {
1684
+ }
1685
+
1686
+ value_type evaluate(const std::vector<parameter_type>& args,
1687
+ std::error_code& ec) const override
1688
+ {
1689
+ if (args.size() != *this->arity())
1690
+ {
1691
+ ec = jsonpath_errc::invalid_arity;
1692
+ return value_type::null();
1693
+ }
1694
+
1695
+ auto arg0= args[0].value();
1696
+ if (!arg0.is_array())
1697
+ {
1698
+ //std::cout << "arg: " << arg0 << "\n";
1699
+ ec = jsonpath_errc::invalid_type;
1700
+ return value_type::null();
1701
+ }
1702
+ if (arg0.empty())
1703
+ {
1704
+ return value_type::null();
1705
+ }
1706
+ bool is_number = arg0.at(0).is_number();
1707
+ bool is_string = arg0.at(0).is_string();
1708
+ if (!is_number && !is_string)
1709
+ {
1710
+ ec = jsonpath_errc::invalid_type;
1711
+ return value_type::null();
1712
+ }
1713
+
1714
+ std::size_t index = 0;
1715
+ for (std::size_t i = 1; i < arg0.size(); ++i)
1716
+ {
1717
+ if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string))
1718
+ {
1719
+ ec = jsonpath_errc::invalid_type;
1720
+ return value_type::null();
1721
+ }
1722
+ if (arg0.at(i) < arg0.at(index))
1723
+ {
1724
+ index = i;
1725
+ }
1726
+ }
1727
+
1728
+ return arg0.at(index);
1729
+ }
1730
+
1731
+ std::string to_string(int level = 0) const override
1732
+ {
1733
+ std::string s;
1734
+ if (level > 0)
1735
+ {
1736
+ s.append("\n");
1737
+ s.append(level*2, ' ');
1738
+ }
1739
+ s.append("min function");
1740
+ return s;
1741
+ }
1742
+ };
1743
+
1744
+ template <class Json>
1745
+ class max_function : public function_base<Json>
1746
+ {
1747
+ public:
1748
+ using value_type = Json;
1749
+ using parameter_type = parameter<Json>;
1750
+
1751
+ max_function()
1752
+ : function_base<Json>(1)
1753
+ {
1754
+ }
1755
+
1756
+ value_type evaluate(const std::vector<parameter_type>& args,
1757
+ std::error_code& ec) const override
1758
+ {
1759
+ if (args.size() != *this->arity())
1760
+ {
1761
+ ec = jsonpath_errc::invalid_arity;
1762
+ return value_type::null();
1763
+ }
1764
+
1765
+ auto arg0= args[0].value();
1766
+ if (!arg0.is_array())
1767
+ {
1768
+ //std::cout << "arg: " << arg0 << "\n";
1769
+ ec = jsonpath_errc::invalid_type;
1770
+ return value_type::null();
1771
+ }
1772
+ if (arg0.empty())
1773
+ {
1774
+ return value_type::null();
1775
+ }
1776
+
1777
+ bool is_number = arg0.at(0).is_number();
1778
+ bool is_string = arg0.at(0).is_string();
1779
+ if (!is_number && !is_string)
1780
+ {
1781
+ ec = jsonpath_errc::invalid_type;
1782
+ return value_type::null();
1783
+ }
1784
+
1785
+ std::size_t index = 0;
1786
+ for (std::size_t i = 1; i < arg0.size(); ++i)
1787
+ {
1788
+ if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string))
1789
+ {
1790
+ ec = jsonpath_errc::invalid_type;
1791
+ return value_type::null();
1792
+ }
1793
+ if (arg0.at(i) > arg0.at(index))
1794
+ {
1795
+ index = i;
1796
+ }
1797
+ }
1798
+
1799
+ return arg0.at(index);
1800
+ }
1801
+
1802
+ std::string to_string(int level = 0) const override
1803
+ {
1804
+ std::string s;
1805
+ if (level > 0)
1806
+ {
1807
+ s.append("\n");
1808
+ s.append(level*2, ' ');
1809
+ }
1810
+ s.append("max function");
1811
+ return s;
1812
+ }
1813
+ };
1814
+
1815
+ template <class Json>
1816
+ class abs_function : public function_base<Json>
1817
+ {
1818
+ public:
1819
+ using value_type = Json;
1820
+ using parameter_type = parameter<Json>;
1821
+
1822
+ abs_function()
1823
+ : function_base<Json>(1)
1824
+ {
1825
+ }
1826
+
1827
+ value_type evaluate(const std::vector<parameter_type>& args,
1828
+ std::error_code& ec) const override
1829
+ {
1830
+ if (args.size() != *this->arity())
1831
+ {
1832
+ ec = jsonpath_errc::invalid_arity;
1833
+ return value_type::null();
1834
+ }
1835
+
1836
+ auto arg0= args[0].value();
1837
+ switch (arg0.type())
1838
+ {
1839
+ case json_type::uint64_value:
1840
+ return arg0;
1841
+ case json_type::int64_value:
1842
+ {
1843
+ return arg0.template as<int64_t>() >= 0 ? arg0 : value_type(std::abs(arg0.template as<int64_t>()));
1844
+ }
1845
+ case json_type::double_value:
1846
+ {
1847
+ return arg0.template as<double>() >= 0 ? arg0 : value_type(std::abs(arg0.template as<double>()));
1848
+ }
1849
+ default:
1850
+ {
1851
+ ec = jsonpath_errc::invalid_type;
1852
+ return value_type::null();
1853
+ }
1854
+ }
1855
+ }
1856
+
1857
+ std::string to_string(int level = 0) const override
1858
+ {
1859
+ std::string s;
1860
+ if (level > 0)
1861
+ {
1862
+ s.append("\n");
1863
+ s.append(level*2, ' ');
1864
+ }
1865
+ s.append("abs function");
1866
+ return s;
1867
+ }
1868
+ };
1869
+
1870
+ template <class Json>
1871
+ class length_function : public function_base<Json>
1872
+ {
1873
+ public:
1874
+ using value_type = Json;
1875
+ using string_view_type = typename Json::string_view_type;
1876
+ using parameter_type = parameter<Json>;
1877
+
1878
+ length_function()
1879
+ : function_base<Json>(1)
1880
+ {
1881
+ }
1882
+
1883
+ value_type evaluate(const std::vector<parameter_type>& args,
1884
+ std::error_code& ec) const override
1885
+ {
1886
+ if (args.size() != *this->arity())
1887
+ {
1888
+ ec = jsonpath_errc::invalid_arity;
1889
+ return value_type::null();
1890
+ }
1891
+
1892
+ auto arg0= args[0].value();
1893
+ //std::cout << "length function arg: " << arg0 << "\n";
1894
+
1895
+ switch (arg0.type())
1896
+ {
1897
+ case json_type::object_value:
1898
+ case json_type::array_value:
1899
+ return value_type(arg0.size());
1900
+ case json_type::string_value:
1901
+ {
1902
+ auto sv0 = arg0.template as<string_view_type>();
1903
+ auto length = unicode_traits::count_codepoints(sv0.data(), sv0.size());
1904
+ return value_type(length);
1905
+ }
1906
+ default:
1907
+ {
1908
+ ec = jsonpath_errc::invalid_type;
1909
+ return value_type::null();
1910
+ }
1911
+ }
1912
+ }
1913
+
1914
+ std::string to_string(int level = 0) const override
1915
+ {
1916
+ std::string s;
1917
+ if (level > 0)
1918
+ {
1919
+ s.append("\n");
1920
+ s.append(level*2, ' ');
1921
+ }
1922
+ s.append("length function");
1923
+ return s;
1924
+ }
1925
+ };
1926
+
1927
+ template <class Json>
1928
+ class keys_function : public function_base<Json>
1929
+ {
1930
+ public:
1931
+ using value_type = Json;
1932
+ using parameter_type = parameter<Json>;
1933
+ using string_view_type = typename Json::string_view_type;
1934
+
1935
+ keys_function()
1936
+ : function_base<Json>(1)
1937
+ {
1938
+ }
1939
+
1940
+ value_type evaluate(const std::vector<parameter_type>& args,
1941
+ std::error_code& ec) const override
1942
+ {
1943
+ if (args.size() != *this->arity())
1944
+ {
1945
+ ec = jsonpath_errc::invalid_arity;
1946
+ return value_type::null();
1947
+ }
1948
+
1949
+ auto arg0= args[0].value();
1950
+ if (!arg0.is_object())
1951
+ {
1952
+ ec = jsonpath_errc::invalid_type;
1953
+ return value_type::null();
1954
+ }
1955
+
1956
+ value_type result(json_array_arg);
1957
+ result.reserve(args.size());
1958
+
1959
+ for (auto& item : arg0.object_range())
1960
+ {
1961
+ result.emplace_back(item.key());
1962
+ }
1963
+ return result;
1964
+ }
1965
+
1966
+ std::string to_string(int level = 0) const override
1967
+ {
1968
+ std::string s;
1969
+ if (level > 0)
1970
+ {
1971
+ s.append("\n");
1972
+ s.append(level*2, ' ');
1973
+ }
1974
+ s.append("keys function");
1975
+ return s;
1976
+ }
1977
+ };
1978
+
1979
+ enum class jsonpath_token_kind
1980
+ {
1981
+ root_node,
1982
+ current_node,
1983
+ expression,
1984
+ lparen,
1985
+ rparen,
1986
+ begin_union,
1987
+ end_union,
1988
+ begin_filter,
1989
+ end_filter,
1990
+ begin_expression,
1991
+ end_index_expression,
1992
+ end_argument_expression,
1993
+ separator,
1994
+ literal,
1995
+ selector,
1996
+ function,
1997
+ end_function,
1998
+ argument,
1999
+ unary_operator,
2000
+ binary_operator
2001
+ };
2002
+
2003
+ inline
2004
+ std::string to_string(jsonpath_token_kind kind)
2005
+ {
2006
+ switch (kind)
2007
+ {
2008
+ case jsonpath_token_kind::root_node:
2009
+ return "root_node";
2010
+ case jsonpath_token_kind::current_node:
2011
+ return "current_node";
2012
+ case jsonpath_token_kind::lparen:
2013
+ return "lparen";
2014
+ case jsonpath_token_kind::rparen:
2015
+ return "rparen";
2016
+ case jsonpath_token_kind::begin_union:
2017
+ return "begin_union";
2018
+ case jsonpath_token_kind::end_union:
2019
+ return "end_union";
2020
+ case jsonpath_token_kind::begin_filter:
2021
+ return "begin_filter";
2022
+ case jsonpath_token_kind::end_filter:
2023
+ return "end_filter";
2024
+ case jsonpath_token_kind::begin_expression:
2025
+ return "begin_expression";
2026
+ case jsonpath_token_kind::end_index_expression:
2027
+ return "end_index_expression";
2028
+ case jsonpath_token_kind::end_argument_expression:
2029
+ return "end_argument_expression";
2030
+ case jsonpath_token_kind::separator:
2031
+ return "separator";
2032
+ case jsonpath_token_kind::literal:
2033
+ return "literal";
2034
+ case jsonpath_token_kind::selector:
2035
+ return "selector";
2036
+ case jsonpath_token_kind::function:
2037
+ return "function";
2038
+ case jsonpath_token_kind::end_function:
2039
+ return "end_function";
2040
+ case jsonpath_token_kind::argument:
2041
+ return "argument";
2042
+ case jsonpath_token_kind::unary_operator:
2043
+ return "unary_operator";
2044
+ case jsonpath_token_kind::binary_operator:
2045
+ return "binary_operator";
2046
+ default:
2047
+ return "";
2048
+ }
2049
+ }
2050
+
2051
+ template <class Json,class JsonReference>
2052
+ struct path_value_pair
2053
+ {
2054
+ using char_type = typename Json::char_type;
2055
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
2056
+ using value_type = Json;
2057
+ using reference = JsonReference;
2058
+ using value_pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
2059
+ using json_location_node_type = json_location_node<char_type>;
2060
+ using json_location_type = json_location<char_type>;
2061
+ using path_pointer = const json_location_node_type*;
2062
+
2063
+ json_location_type path_;
2064
+ value_pointer value_ptr_;
2065
+
2066
+ path_value_pair(const json_location_type& path, reference value) noexcept
2067
+ : path_(path), value_ptr_(std::addressof(value))
2068
+ {
2069
+ }
2070
+
2071
+ path_value_pair(json_location_type&& path, value_pointer valp) noexcept
2072
+ : path_(std::move(path)), value_ptr_(valp)
2073
+ {
2074
+ }
2075
+
2076
+ path_value_pair(const path_value_pair&) = default;
2077
+ path_value_pair(path_value_pair&& other) = default;
2078
+ path_value_pair& operator=(const path_value_pair&) = default;
2079
+ path_value_pair& operator=(path_value_pair&& other) = default;
2080
+
2081
+ json_location_type path() const
2082
+ {
2083
+ return path_;
2084
+ }
2085
+
2086
+ reference value()
2087
+ {
2088
+ return *value_ptr_;
2089
+ }
2090
+ };
2091
+
2092
+ template <class Json,class JsonReference>
2093
+ struct path_value_pair_less
2094
+ {
2095
+ bool operator()(const path_value_pair<Json,JsonReference>& lhs,
2096
+ const path_value_pair<Json,JsonReference>& rhs) const noexcept
2097
+ {
2098
+ return lhs.path() < rhs.path();
2099
+ }
2100
+ };
2101
+
2102
+ template <class Json,class JsonReference>
2103
+ struct path_value_pair_equal
2104
+ {
2105
+ bool operator()(const path_value_pair<Json,JsonReference>& lhs,
2106
+ const path_value_pair<Json,JsonReference>& rhs) const noexcept
2107
+ {
2108
+ return lhs.path() == rhs.path();
2109
+ }
2110
+ };
2111
+
2112
+ template <class Json,class JsonReference>
2113
+ struct path_component_value_pair
2114
+ {
2115
+ using char_type = typename Json::char_type;
2116
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
2117
+ using value_type = Json;
2118
+ using reference = JsonReference;
2119
+ using value_pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
2120
+ using json_location_node_type = json_location_node<char_type>;
2121
+ using json_location_type = json_location<char_type>;
2122
+ using path_pointer = const json_location_node_type*;
2123
+ private:
2124
+ const json_location_node_type* last_ptr_;
2125
+ value_pointer value_ptr_;
2126
+ public:
2127
+ path_component_value_pair(const json_location_node_type& last, reference value) noexcept
2128
+ : last_ptr_(std::addressof(last)), value_ptr_(std::addressof(value))
2129
+ {
2130
+ }
2131
+
2132
+ const json_location_node_type& last() const
2133
+ {
2134
+ return *last_ptr_;
2135
+ }
2136
+
2137
+ reference value() const
2138
+ {
2139
+ return *value_ptr_;
2140
+ }
2141
+ };
2142
+
2143
+ template <class Json,class JsonReference>
2144
+ class node_receiver
2145
+ {
2146
+ public:
2147
+ using char_type = typename Json::char_type;
2148
+ using reference = JsonReference;
2149
+ using json_location_node_type = json_location_node<char_type>;
2150
+
2151
+ virtual ~node_receiver() noexcept = default;
2152
+
2153
+ virtual void add(const json_location_node_type& path_tail,
2154
+ reference value) = 0;
2155
+ };
2156
+
2157
+ template <class Json,class JsonReference>
2158
+ class path_value_receiver : public node_receiver<Json,JsonReference>
2159
+ {
2160
+ public:
2161
+ using reference = JsonReference;
2162
+ using char_type = typename Json::char_type;
2163
+ using json_location_node_type = json_location_node<char_type>;
2164
+ using json_location_type = json_location<char_type>;
2165
+ using path_value_pair_type = path_value_pair<Json,JsonReference>;
2166
+
2167
+ std::vector<path_value_pair_type> nodes;
2168
+
2169
+ void add(const json_location_node_type& path_tail,
2170
+ reference value) override
2171
+ {
2172
+ nodes.emplace_back(json_location_type(path_tail), std::addressof(value));
2173
+ }
2174
+ };
2175
+
2176
+ template <class Json,class JsonReference>
2177
+ class path_stem_value_receiver : public node_receiver<Json,JsonReference>
2178
+ {
2179
+ public:
2180
+ using reference = JsonReference;
2181
+ using char_type = typename Json::char_type;
2182
+ using json_location_node_type = json_location_node<char_type>;
2183
+ using path_stem_value_pair_type = path_component_value_pair<Json,JsonReference>;
2184
+
2185
+ std::vector<path_stem_value_pair_type> nodes;
2186
+
2187
+ void add(const json_location_node_type& path_tail,
2188
+ reference value) override
2189
+ {
2190
+ nodes.emplace_back(path_tail, value);
2191
+ }
2192
+ };
2193
+
2194
+ template <class Json, class JsonReference>
2195
+ class dynamic_resources
2196
+ {
2197
+ using reference = JsonReference;
2198
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<reference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
2199
+ using json_location_node_type = json_location_node<typename Json::char_type>;
2200
+ using path_stem_value_pair_type = path_component_value_pair<Json,JsonReference>;
2201
+ std::vector<std::unique_ptr<Json>> temp_json_values_;
2202
+ std::vector<std::unique_ptr<json_location_node_type>> temp_path_node_values_;
2203
+ std::unordered_map<std::size_t,pointer> cache_;
2204
+ public:
2205
+ bool is_cached(std::size_t id) const
2206
+ {
2207
+ return cache_.find(id) != cache_.end();
2208
+ }
2209
+ void add_to_cache(std::size_t id, reference val)
2210
+ {
2211
+ cache_.emplace(id, std::addressof(val));
2212
+ }
2213
+ reference retrieve_from_cache(std::size_t id)
2214
+ {
2215
+ return *cache_[id];
2216
+ }
2217
+
2218
+ reference null_value()
2219
+ {
2220
+ static Json j{ null_type{} };
2221
+ return j;
2222
+ }
2223
+
2224
+ template <typename... Args>
2225
+ Json* create_json(Args&& ... args)
2226
+ {
2227
+ auto temp = jsoncons::make_unique<Json>(std::forward<Args>(args)...);
2228
+ Json* ptr = temp.get();
2229
+ temp_json_values_.emplace_back(std::move(temp));
2230
+ return ptr;
2231
+ }
2232
+
2233
+ const json_location_node_type& root_path_node() const
2234
+ {
2235
+ static json_location_node_type root('$');
2236
+ return root;
2237
+ }
2238
+
2239
+ const json_location_node_type& current_path_node() const
2240
+ {
2241
+ static json_location_node_type root('@');
2242
+ return root;
2243
+ }
2244
+
2245
+ template <typename... Args>
2246
+ const json_location_node_type* create_path_node(Args&& ... args)
2247
+ {
2248
+ auto temp = jsoncons::make_unique<json_location_node_type>(std::forward<Args>(args)...);
2249
+ json_location_node_type* ptr = temp.get();
2250
+ temp_path_node_values_.emplace_back(std::move(temp));
2251
+ return ptr;
2252
+ }
2253
+ };
2254
+
2255
+ template <class Json,class JsonReference>
2256
+ struct node_less
2257
+ {
2258
+ bool operator()(const path_value_pair<Json,JsonReference>& a, const path_value_pair<Json,JsonReference>& b) const
2259
+ {
2260
+ return *(a.ptr) < *(b.ptr);
2261
+ }
2262
+ };
2263
+
2264
+ template <class Json,class JsonReference>
2265
+ class jsonpath_selector
2266
+ {
2267
+ bool is_path_;
2268
+ std::size_t precedence_level_;
2269
+
2270
+ public:
2271
+ using char_type = typename Json::char_type;
2272
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
2273
+ using string_view_type = jsoncons::basic_string_view<char_type, std::char_traits<char_type>>;
2274
+ using value_type = Json;
2275
+ using reference = JsonReference;
2276
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
2277
+ using path_value_pair_type = path_value_pair<Json,JsonReference>;
2278
+ using json_location_node_type = json_location_node<char_type>;
2279
+ using json_location_type = json_location<char_type>;
2280
+ using node_receiver_type = node_receiver<Json,JsonReference>;
2281
+ using selector_type = jsonpath_selector<Json,JsonReference>;
2282
+
2283
+ jsonpath_selector(bool is_path,
2284
+ std::size_t precedence_level = 0)
2285
+ : is_path_(is_path),
2286
+ precedence_level_(precedence_level)
2287
+ {
2288
+ }
2289
+
2290
+ virtual ~jsonpath_selector() noexcept = default;
2291
+
2292
+ bool is_path() const
2293
+ {
2294
+ return is_path_;
2295
+ }
2296
+
2297
+ std::size_t precedence_level() const
2298
+ {
2299
+ return precedence_level_;
2300
+ }
2301
+
2302
+ bool is_right_associative() const
2303
+ {
2304
+ return true;
2305
+ }
2306
+
2307
+ virtual void select(dynamic_resources<Json,JsonReference>& resources,
2308
+ reference root,
2309
+ const json_location_node_type& path_tail,
2310
+ reference val,
2311
+ node_receiver_type& receiver,
2312
+ result_options options) const = 0;
2313
+
2314
+ virtual reference evaluate(dynamic_resources<Json,JsonReference>& resources,
2315
+ reference root,
2316
+ const json_location_node_type& path_tail,
2317
+ reference current,
2318
+ result_options options,
2319
+ std::error_code& ec) const = 0;
2320
+
2321
+ virtual void append_selector(jsonpath_selector*)
2322
+ {
2323
+ }
2324
+
2325
+ virtual std::string to_string(int = 0) const
2326
+ {
2327
+ return std::string();
2328
+ }
2329
+ };
2330
+
2331
+ template <class Json, class JsonReference>
2332
+ struct static_resources
2333
+ {
2334
+ using char_type = typename Json::char_type;
2335
+ using string_type = std::basic_string<char_type>;
2336
+ using value_type = Json;
2337
+ using reference = JsonReference;
2338
+ using function_base_type = function_base<Json>;
2339
+ using selector_type = jsonpath_selector<Json,JsonReference>;
2340
+
2341
+ std::vector<std::unique_ptr<selector_type>> selectors_;
2342
+ std::vector<std::unique_ptr<Json>> temp_json_values_;
2343
+ std::vector<std::unique_ptr<unary_operator<Json,JsonReference>>> unary_operators_;
2344
+ std::unordered_map<string_type,std::unique_ptr<function_base_type>> custom_functions_;
2345
+
2346
+ static_resources()
2347
+ {
2348
+ }
2349
+
2350
+ static_resources(const custom_functions<Json>& functions)
2351
+ {
2352
+ for (const auto& item : functions)
2353
+ {
2354
+ custom_functions_.emplace(item.name(),
2355
+ jsoncons::make_unique<decorator_function<Json>>(item.arity(),item.function()));
2356
+ }
2357
+ }
2358
+
2359
+ static_resources(const static_resources&) = default;
2360
+
2361
+ static_resources(static_resources&& other) noexcept
2362
+ : selectors_(std::move(other.selectors_)),
2363
+ temp_json_values_(std::move(other.temp_json_values_)),
2364
+ unary_operators_(std::move(other.unary_operators_)),
2365
+ custom_functions_(std::move(other.custom_functions_))
2366
+ {
2367
+ }
2368
+
2369
+ const function_base_type* get_function(const string_type& name, std::error_code& ec) const
2370
+ {
2371
+ static abs_function<Json> abs_func;
2372
+ static contains_function<Json> contains_func;
2373
+ static starts_with_function<Json> starts_with_func;
2374
+ static ends_with_function<Json> ends_with_func;
2375
+ static ceil_function<Json> ceil_func;
2376
+ static floor_function<Json> floor_func;
2377
+ static to_number_function<Json> to_number_func;
2378
+ static sum_function<Json> sum_func;
2379
+ static prod_function<Json> prod_func;
2380
+ static avg_function<Json> avg_func;
2381
+ static min_function<Json> min_func;
2382
+ static max_function<Json> max_func;
2383
+ static length_function<Json> length_func;
2384
+ static keys_function<Json> keys_func;
2385
+ #if defined(JSONCONS_HAS_STD_REGEX)
2386
+ static tokenize_function<Json> tokenize_func;
2387
+ #endif
2388
+
2389
+ static std::unordered_map<string_type,const function_base_type*> functions =
2390
+ {
2391
+ {string_type{'a','b','s'}, &abs_func},
2392
+ {string_type{'c','o','n','t','a','i','n','s'}, &contains_func},
2393
+ {string_type{'s','t','a','r','t','s','_','w','i','t','h'}, &starts_with_func},
2394
+ {string_type{'e','n','d','s','_','w','i','t','h'}, &ends_with_func},
2395
+ {string_type{'c','e','i','l'}, &ceil_func},
2396
+ {string_type{'f','l','o','o','r'}, &floor_func},
2397
+ {string_type{'t','o','_','n','u','m','b','e','r'}, &to_number_func},
2398
+ {string_type{'s','u','m'}, &sum_func},
2399
+ {string_type{'p','r','o', 'd'}, &prod_func},
2400
+ {string_type{'a','v','g'}, &avg_func},
2401
+ {string_type{'m','i','n'}, &min_func},
2402
+ {string_type{'m','a','x'}, &max_func},
2403
+ {string_type{'l','e','n','g','t','h'}, &length_func},
2404
+ {string_type{'k','e','y','s'}, &keys_func},
2405
+ #if defined(JSONCONS_HAS_STD_REGEX)
2406
+ {string_type{'t','o','k','e','n','i','z','e'}, &tokenize_func},
2407
+ #endif
2408
+ {string_type{'c','o','u','n','t'}, &length_func}
2409
+ };
2410
+
2411
+ auto it = functions.find(name);
2412
+ if (it == functions.end())
2413
+ {
2414
+ auto it2 = custom_functions_.find(name);
2415
+ if (it2 == custom_functions_.end())
2416
+ {
2417
+ ec = jsonpath_errc::unknown_function;
2418
+ return nullptr;
2419
+ }
2420
+ else
2421
+ {
2422
+ return it2->second.get();
2423
+ }
2424
+ }
2425
+ else
2426
+ {
2427
+ return it->second;
2428
+ }
2429
+ }
2430
+
2431
+ const unary_operator<Json,JsonReference>* get_unary_not() const
2432
+ {
2433
+ static unary_not_operator<Json,JsonReference> oper;
2434
+ return &oper;
2435
+ }
2436
+
2437
+ const unary_operator<Json,JsonReference>* get_unary_minus() const
2438
+ {
2439
+ static unary_minus_operator<Json,JsonReference> oper;
2440
+ return &oper;
2441
+ }
2442
+
2443
+ const unary_operator<Json,JsonReference>* get_regex_operator(std::basic_regex<char_type>&& pattern)
2444
+ {
2445
+ unary_operators_.push_back(jsoncons::make_unique<regex_operator<Json,JsonReference>>(std::move(pattern)));
2446
+ return unary_operators_.back().get();
2447
+ }
2448
+
2449
+ const binary_operator<Json,JsonReference>* get_or_operator() const
2450
+ {
2451
+ static or_operator<Json,JsonReference> oper;
2452
+
2453
+ return &oper;
2454
+ }
2455
+
2456
+ const binary_operator<Json,JsonReference>* get_and_operator() const
2457
+ {
2458
+ static and_operator<Json,JsonReference> oper;
2459
+
2460
+ return &oper;
2461
+ }
2462
+
2463
+ const binary_operator<Json,JsonReference>* get_eq_operator() const
2464
+ {
2465
+ static eq_operator<Json,JsonReference> oper;
2466
+ return &oper;
2467
+ }
2468
+
2469
+ const binary_operator<Json,JsonReference>* get_ne_operator() const
2470
+ {
2471
+ static ne_operator<Json,JsonReference> oper;
2472
+ return &oper;
2473
+ }
2474
+
2475
+ const binary_operator<Json,JsonReference>* get_lt_operator() const
2476
+ {
2477
+ static lt_operator<Json,JsonReference> oper;
2478
+ return &oper;
2479
+ }
2480
+
2481
+ const binary_operator<Json,JsonReference>* get_lte_operator() const
2482
+ {
2483
+ static lte_operator<Json,JsonReference> oper;
2484
+ return &oper;
2485
+ }
2486
+
2487
+ const binary_operator<Json,JsonReference>* get_gt_operator() const
2488
+ {
2489
+ static gt_operator<Json,JsonReference> oper;
2490
+ return &oper;
2491
+ }
2492
+
2493
+ const binary_operator<Json,JsonReference>* get_gte_operator() const
2494
+ {
2495
+ static gte_operator<Json,JsonReference> oper;
2496
+ return &oper;
2497
+ }
2498
+
2499
+ const binary_operator<Json,JsonReference>* get_plus_operator() const
2500
+ {
2501
+ static plus_operator<Json,JsonReference> oper;
2502
+ return &oper;
2503
+ }
2504
+
2505
+ const binary_operator<Json,JsonReference>* get_minus_operator() const
2506
+ {
2507
+ static minus_operator<Json,JsonReference> oper;
2508
+ return &oper;
2509
+ }
2510
+
2511
+ const binary_operator<Json,JsonReference>* get_mult_operator() const
2512
+ {
2513
+ static mult_operator<Json,JsonReference> oper;
2514
+ return &oper;
2515
+ }
2516
+
2517
+ const binary_operator<Json,JsonReference>* get_div_operator() const
2518
+ {
2519
+ static div_operator<Json,JsonReference> oper;
2520
+ return &oper;
2521
+ }
2522
+
2523
+ const binary_operator<Json,JsonReference>* get_modulus_operator() const
2524
+ {
2525
+ static modulus_operator<Json,JsonReference> oper;
2526
+ return &oper;
2527
+ }
2528
+
2529
+ template <typename T>
2530
+ selector_type* new_selector(T&& val)
2531
+ {
2532
+ selectors_.emplace_back(jsoncons::make_unique<T>(std::forward<T>(val)));
2533
+ return selectors_.back().get();
2534
+ }
2535
+
2536
+ template <typename... Args>
2537
+ Json* create_json(Args&& ... args)
2538
+ {
2539
+ auto temp = jsoncons::make_unique<Json>(std::forward<Args>(args)...);
2540
+ Json* ptr = temp.get();
2541
+ temp_json_values_.emplace_back(std::move(temp));
2542
+ return ptr;
2543
+ }
2544
+ };
2545
+
2546
+ template <class Json, class JsonReference>
2547
+ class expression_base
2548
+ {
2549
+ public:
2550
+ using char_type = typename Json::char_type;
2551
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
2552
+ using string_view_type = jsoncons::basic_string_view<char_type, std::char_traits<char_type>>;
2553
+ using value_type = Json;
2554
+ using reference = JsonReference;
2555
+ using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
2556
+ using path_value_pair_type = path_value_pair<Json,JsonReference>;
2557
+ using json_location_node_type = json_location_node<char_type>;
2558
+
2559
+ virtual ~expression_base() noexcept = default;
2560
+
2561
+ virtual value_type evaluate(dynamic_resources<Json,JsonReference>& resources,
2562
+ reference root,
2563
+ //const json_location_node_type& path,
2564
+ reference val,
2565
+ result_options options,
2566
+ std::error_code& ec) const = 0;
2567
+
2568
+ virtual std::string to_string(int level = 0) const = 0;
2569
+ };
2570
+
2571
+ template <class Json,class JsonReference>
2572
+ class token
2573
+ {
2574
+ public:
2575
+ using selector_type = jsonpath_selector<Json,JsonReference>;
2576
+ using expression_base_type = expression_base<Json,JsonReference>;
2577
+
2578
+ jsonpath_token_kind token_kind_;
2579
+
2580
+ union
2581
+ {
2582
+ selector_type* selector_;
2583
+ std::unique_ptr<expression_base_type> expression_;
2584
+ const unary_operator<Json,JsonReference>* unary_operator_;
2585
+ const binary_operator<Json,JsonReference>* binary_operator_;
2586
+ const function_base<Json>* function_;
2587
+ Json value_;
2588
+ };
2589
+ public:
2590
+
2591
+ token(const unary_operator<Json,JsonReference>* expr) noexcept
2592
+ : token_kind_(jsonpath_token_kind::unary_operator),
2593
+ unary_operator_(expr)
2594
+ {
2595
+ }
2596
+
2597
+ token(const binary_operator<Json,JsonReference>* expr) noexcept
2598
+ : token_kind_(jsonpath_token_kind::binary_operator),
2599
+ binary_operator_(expr)
2600
+ {
2601
+ }
2602
+
2603
+ token(current_node_arg_t) noexcept
2604
+ : token_kind_(jsonpath_token_kind::current_node)
2605
+ {
2606
+ }
2607
+
2608
+ token(root_node_arg_t) noexcept
2609
+ : token_kind_(jsonpath_token_kind::root_node)
2610
+ {
2611
+ }
2612
+
2613
+ token(end_function_arg_t) noexcept
2614
+ : token_kind_(jsonpath_token_kind::end_function)
2615
+ {
2616
+ }
2617
+
2618
+ token(separator_arg_t) noexcept
2619
+ : token_kind_(jsonpath_token_kind::separator)
2620
+ {
2621
+ }
2622
+
2623
+ token(lparen_arg_t) noexcept
2624
+ : token_kind_(jsonpath_token_kind::lparen)
2625
+ {
2626
+ }
2627
+
2628
+ token(rparen_arg_t) noexcept
2629
+ : token_kind_(jsonpath_token_kind::rparen)
2630
+ {
2631
+ }
2632
+
2633
+ token(begin_union_arg_t) noexcept
2634
+ : token_kind_(jsonpath_token_kind::begin_union)
2635
+ {
2636
+ }
2637
+
2638
+ token(end_union_arg_t) noexcept
2639
+ : token_kind_(jsonpath_token_kind::end_union)
2640
+ {
2641
+ }
2642
+
2643
+ token(begin_filter_arg_t) noexcept
2644
+ : token_kind_(jsonpath_token_kind::begin_filter)
2645
+ {
2646
+ }
2647
+
2648
+ token(end_filter_arg_t) noexcept
2649
+ : token_kind_(jsonpath_token_kind::end_filter)
2650
+ {
2651
+ }
2652
+
2653
+ token(begin_expression_arg_t) noexcept
2654
+ : token_kind_(jsonpath_token_kind::begin_expression)
2655
+ {
2656
+ }
2657
+
2658
+ token(end_index_expression_arg_t) noexcept
2659
+ : token_kind_(jsonpath_token_kind::end_index_expression)
2660
+ {
2661
+ }
2662
+
2663
+ token(end_argument_expression_arg_t) noexcept
2664
+ : token_kind_(jsonpath_token_kind::end_argument_expression)
2665
+ {
2666
+ }
2667
+
2668
+ token(selector_type* selector)
2669
+ : token_kind_(jsonpath_token_kind::selector), selector_(selector)
2670
+ {
2671
+ }
2672
+
2673
+ token(std::unique_ptr<expression_base_type>&& expr)
2674
+ : token_kind_(jsonpath_token_kind::expression)
2675
+ {
2676
+ new (&expression_) std::unique_ptr<expression_base_type>(std::move(expr));
2677
+ }
2678
+
2679
+ token(const function_base<Json>* function) noexcept
2680
+ : token_kind_(jsonpath_token_kind::function),
2681
+ function_(function)
2682
+ {
2683
+ }
2684
+
2685
+ token(argument_arg_t) noexcept
2686
+ : token_kind_(jsonpath_token_kind::argument)
2687
+ {
2688
+ }
2689
+
2690
+ token(literal_arg_t, Json&& value) noexcept
2691
+ : token_kind_(jsonpath_token_kind::literal), value_(std::move(value))
2692
+ {
2693
+ }
2694
+
2695
+ token(token&& other) noexcept
2696
+ {
2697
+ construct(std::forward<token>(other));
2698
+ }
2699
+
2700
+ const Json& get_value(const_reference_arg_t, dynamic_resources<Json,JsonReference>&) const
2701
+ {
2702
+ return value_;
2703
+ }
2704
+
2705
+ Json& get_value(reference_arg_t, dynamic_resources<Json,JsonReference>& resources) const
2706
+ {
2707
+ return *resources.create_json(value_);
2708
+ }
2709
+
2710
+ token& operator=(token&& other)
2711
+ {
2712
+ if (&other != this)
2713
+ {
2714
+ if (token_kind_ == other.token_kind_)
2715
+ {
2716
+ switch (token_kind_)
2717
+ {
2718
+ case jsonpath_token_kind::selector:
2719
+ selector_ = other.selector_;
2720
+ break;
2721
+ case jsonpath_token_kind::expression:
2722
+ expression_ = std::move(other.expression_);
2723
+ break;
2724
+ case jsonpath_token_kind::unary_operator:
2725
+ unary_operator_ = other.unary_operator_;
2726
+ break;
2727
+ case jsonpath_token_kind::binary_operator:
2728
+ binary_operator_ = other.binary_operator_;
2729
+ break;
2730
+ case jsonpath_token_kind::function:
2731
+ function_ = other.function_;
2732
+ break;
2733
+ case jsonpath_token_kind::literal:
2734
+ value_ = std::move(other.value_);
2735
+ break;
2736
+ default:
2737
+ break;
2738
+ }
2739
+ }
2740
+ else
2741
+ {
2742
+ destroy();
2743
+ construct(std::forward<token>(other));
2744
+ }
2745
+ }
2746
+ return *this;
2747
+ }
2748
+
2749
+ ~token() noexcept
2750
+ {
2751
+ destroy();
2752
+ }
2753
+
2754
+ jsonpath_token_kind token_kind() const
2755
+ {
2756
+ return token_kind_;
2757
+ }
2758
+
2759
+ bool is_lparen() const
2760
+ {
2761
+ return token_kind_ == jsonpath_token_kind::lparen;
2762
+ }
2763
+
2764
+ bool is_rparen() const
2765
+ {
2766
+ return token_kind_ == jsonpath_token_kind::rparen;
2767
+ }
2768
+
2769
+ bool is_current_node() const
2770
+ {
2771
+ return token_kind_ == jsonpath_token_kind::current_node;
2772
+ }
2773
+
2774
+ bool is_path() const
2775
+ {
2776
+ return token_kind_ == jsonpath_token_kind::selector && selector_->is_path();
2777
+ }
2778
+
2779
+ bool is_operator() const
2780
+ {
2781
+ return token_kind_ == jsonpath_token_kind::unary_operator ||
2782
+ token_kind_ == jsonpath_token_kind::binary_operator;
2783
+ }
2784
+
2785
+ std::size_t precedence_level() const
2786
+ {
2787
+ switch(token_kind_)
2788
+ {
2789
+ case jsonpath_token_kind::selector:
2790
+ return selector_->precedence_level();
2791
+ case jsonpath_token_kind::unary_operator:
2792
+ return unary_operator_->precedence_level();
2793
+ case jsonpath_token_kind::binary_operator:
2794
+ return binary_operator_->precedence_level();
2795
+ default:
2796
+ return 0;
2797
+ }
2798
+ }
2799
+
2800
+ jsoncons::optional<std::size_t> arity() const
2801
+ {
2802
+ return token_kind_ == jsonpath_token_kind::function ? function_->arity() : jsoncons::optional<std::size_t>();
2803
+ }
2804
+
2805
+ bool is_right_associative() const
2806
+ {
2807
+ switch(token_kind_)
2808
+ {
2809
+ case jsonpath_token_kind::selector:
2810
+ return selector_->is_right_associative();
2811
+ case jsonpath_token_kind::unary_operator:
2812
+ return unary_operator_->is_right_associative();
2813
+ case jsonpath_token_kind::binary_operator:
2814
+ return binary_operator_->is_right_associative();
2815
+ default:
2816
+ return false;
2817
+ }
2818
+ }
2819
+
2820
+ void construct(token&& other)
2821
+ {
2822
+ token_kind_ = other.token_kind_;
2823
+ switch (token_kind_)
2824
+ {
2825
+ case jsonpath_token_kind::selector:
2826
+ selector_ = other.selector_;
2827
+ break;
2828
+ case jsonpath_token_kind::expression:
2829
+ new (&expression_) std::unique_ptr<expression_base_type>(std::move(other.expression_));
2830
+ break;
2831
+ case jsonpath_token_kind::unary_operator:
2832
+ unary_operator_ = other.unary_operator_;
2833
+ break;
2834
+ case jsonpath_token_kind::binary_operator:
2835
+ binary_operator_ = other.binary_operator_;
2836
+ break;
2837
+ case jsonpath_token_kind::function:
2838
+ function_ = other.function_;
2839
+ break;
2840
+ case jsonpath_token_kind::literal:
2841
+ new (&value_) Json(std::move(other.value_));
2842
+ break;
2843
+ default:
2844
+ break;
2845
+ }
2846
+ }
2847
+
2848
+ void destroy() noexcept
2849
+ {
2850
+ switch(token_kind_)
2851
+ {
2852
+ case jsonpath_token_kind::expression:
2853
+ expression_.~unique_ptr();
2854
+ break;
2855
+ case jsonpath_token_kind::literal:
2856
+ value_.~Json();
2857
+ break;
2858
+ default:
2859
+ break;
2860
+ }
2861
+ }
2862
+
2863
+ std::string to_string(int level = 0) const
2864
+ {
2865
+ std::string s;
2866
+ switch (token_kind_)
2867
+ {
2868
+ case jsonpath_token_kind::root_node:
2869
+ if (level > 0)
2870
+ {
2871
+ s.append("\n");
2872
+ s.append(level*2, ' ');
2873
+ }
2874
+ s.append("root node");
2875
+ break;
2876
+ case jsonpath_token_kind::current_node:
2877
+ if (level > 0)
2878
+ {
2879
+ s.append("\n");
2880
+ s.append(level*2, ' ');
2881
+ }
2882
+ s.append("current node");
2883
+ break;
2884
+ case jsonpath_token_kind::argument:
2885
+ if (level > 0)
2886
+ {
2887
+ s.append("\n");
2888
+ s.append(level*2, ' ');
2889
+ }
2890
+ s.append("argument");
2891
+ break;
2892
+ case jsonpath_token_kind::selector:
2893
+ s.append(selector_->to_string(level));
2894
+ break;
2895
+ case jsonpath_token_kind::expression:
2896
+ s.append(expression_->to_string(level));
2897
+ break;
2898
+ case jsonpath_token_kind::literal:
2899
+ {
2900
+ if (level > 0)
2901
+ {
2902
+ s.append("\n");
2903
+ s.append(level*2, ' ');
2904
+ }
2905
+ auto sbuf = value_.to_string();
2906
+ unicode_traits::convert(sbuf.data(), sbuf.size(), s);
2907
+ break;
2908
+ }
2909
+ case jsonpath_token_kind::binary_operator:
2910
+ s.append(binary_operator_->to_string(level));
2911
+ break;
2912
+ case jsonpath_token_kind::function:
2913
+ s.append(function_->to_string(level));
2914
+ break;
2915
+ default:
2916
+ if (level > 0)
2917
+ {
2918
+ s.append("\n");
2919
+ s.append(level*2, ' ');
2920
+ }
2921
+ s.append("token kind: ");
2922
+ s.append(jsoncons::jsonpath::detail::to_string(token_kind_));
2923
+ break;
2924
+ }
2925
+ //s.append("\n");
2926
+ return s;
2927
+ }
2928
+ };
2929
+
2930
+ template <class Callback, class Json,class JsonReference>
2931
+ class callback_receiver : public node_receiver<Json,JsonReference>
2932
+ {
2933
+ Callback& callback_;
2934
+ public:
2935
+ using reference = JsonReference;
2936
+ using char_type = typename Json::char_type;
2937
+ using json_location_node_type = json_location_node<char_type>;
2938
+ using json_location_type = json_location<char_type>;
2939
+
2940
+ callback_receiver(Callback& callback)
2941
+ : callback_(callback)
2942
+ {
2943
+ }
2944
+
2945
+ void add(const json_location_node_type& path_tail,
2946
+ reference value) override
2947
+ {
2948
+ callback_(json_location_type(path_tail), value);
2949
+ }
2950
+ };
2951
+
2952
+ template <class Json,class JsonReference>
2953
+ class path_expression
2954
+ {
2955
+ public:
2956
+ using char_type = typename Json::char_type;
2957
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
2958
+ using string_view_type = typename Json::string_view_type;
2959
+ using path_value_pair_type = path_value_pair<Json,JsonReference>;
2960
+ using path_value_pair_less_type = path_value_pair_less<Json,JsonReference>;
2961
+ using path_value_pair_equal_type = path_value_pair_equal<Json,JsonReference>;
2962
+ using value_type = Json;
2963
+ using reference = typename path_value_pair_type::reference;
2964
+ using pointer = typename path_value_pair_type::value_pointer;
2965
+ using token_type = token<Json,JsonReference>;
2966
+ using reference_arg_type = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,
2967
+ const_reference_arg_t,reference_arg_t>::type;
2968
+ using json_location_node_type = json_location_node<char_type>;
2969
+ using json_location_type = json_location<char_type>;
2970
+ using selector_type = jsonpath_selector<Json,JsonReference>;
2971
+ private:
2972
+ selector_type* selector_;
2973
+ result_options required_options_;
2974
+ public:
2975
+
2976
+ path_expression()
2977
+ : required_options_()
2978
+ {
2979
+ }
2980
+
2981
+ path_expression(path_expression&& expr) = default;
2982
+
2983
+ path_expression(selector_type* selector, bool paths_required)
2984
+ : selector_(selector), required_options_()
2985
+ {
2986
+ if (paths_required)
2987
+ {
2988
+ required_options_ |= result_options::path;
2989
+ }
2990
+ }
2991
+
2992
+ path_expression& operator=(path_expression&& expr) = default;
2993
+
2994
+ Json evaluate(dynamic_resources<Json,JsonReference>& resources,
2995
+ reference root,
2996
+ const json_location_node_type& path,
2997
+ reference instance,
2998
+ result_options options) const
2999
+ {
3000
+ Json result(json_array_arg);
3001
+
3002
+ if ((options & result_options::path) == result_options::path)
3003
+ {
3004
+ auto callback = [&result](const json_location_type& path, reference)
3005
+ {
3006
+ result.emplace_back(path.to_string());
3007
+ };
3008
+ evaluate(resources, root, path, instance, callback, options);
3009
+ }
3010
+ else
3011
+ {
3012
+ auto callback = [&result](const json_location_type&, reference val)
3013
+ {
3014
+ result.push_back(val);
3015
+ };
3016
+ evaluate(resources, root, path, instance, callback, options);
3017
+ }
3018
+
3019
+ return result;
3020
+ }
3021
+
3022
+ template <class Callback>
3023
+ typename std::enable_if<traits_extension::is_binary_function_object<Callback,const json_location_type&,reference>::value,void>::type
3024
+ evaluate(dynamic_resources<Json,JsonReference>& resources,
3025
+ reference root,
3026
+ const json_location_node_type& path,
3027
+ reference current,
3028
+ Callback callback,
3029
+ result_options options) const
3030
+ {
3031
+ std::error_code ec;
3032
+
3033
+ options |= required_options_;
3034
+
3035
+ const result_options require_more = result_options::nodups | result_options::sort;
3036
+
3037
+ if ((options & require_more) != result_options())
3038
+ {
3039
+ path_value_receiver<Json,JsonReference> receiver;
3040
+ selector_->select(resources, root, path, current, receiver, options);
3041
+
3042
+ if (receiver.nodes.size() > 1 && (options & result_options::sort) == result_options::sort)
3043
+ {
3044
+ std::sort(receiver.nodes.begin(), receiver.nodes.end(), path_value_pair_less_type());
3045
+ }
3046
+
3047
+ if (receiver.nodes.size() > 1 && (options & result_options::nodups) == result_options::nodups)
3048
+ {
3049
+ if ((options & result_options::sort) == result_options::sort)
3050
+ {
3051
+ auto last = std::unique(receiver.nodes.begin(),receiver.nodes.end(),path_value_pair_equal_type());
3052
+ receiver.nodes.erase(last,receiver.nodes.end());
3053
+ for (auto& node : receiver.nodes)
3054
+ {
3055
+ callback(node.path(), node.value());
3056
+ }
3057
+ }
3058
+ else
3059
+ {
3060
+ std::vector<path_value_pair_type> index(receiver.nodes);
3061
+ std::sort(index.begin(), index.end(), path_value_pair_less_type());
3062
+ auto last = std::unique(index.begin(),index.end(),path_value_pair_equal_type());
3063
+ index.erase(last,index.end());
3064
+
3065
+ std::vector<path_value_pair_type> temp2;
3066
+ temp2.reserve(index.size());
3067
+ for (auto&& node : receiver.nodes)
3068
+ {
3069
+ auto it = std::lower_bound(index.begin(),index.end(),node, path_value_pair_less_type());
3070
+ if (it != index.end() && it->path() == node.path())
3071
+ {
3072
+ temp2.emplace_back(std::move(node));
3073
+ index.erase(it);
3074
+ }
3075
+ }
3076
+ for (auto& node : temp2)
3077
+ {
3078
+ callback(node.path(), node.value());
3079
+ }
3080
+ }
3081
+ }
3082
+ else
3083
+ {
3084
+ for (auto& node : receiver.nodes)
3085
+ {
3086
+ callback(node.path(), node.value());
3087
+ }
3088
+ }
3089
+ }
3090
+ else
3091
+ {
3092
+ callback_receiver<Callback,Json,JsonReference> receiver(callback);
3093
+ selector_->select(resources, root, path, current, receiver, options);
3094
+ }
3095
+ }
3096
+
3097
+ std::string to_string(int level) const
3098
+ {
3099
+ std::string s;
3100
+ if (level > 0)
3101
+ {
3102
+ s.append("\n");
3103
+ s.append(level*2, ' ');
3104
+ }
3105
+ s.append("expression ");
3106
+ s.append(selector_->to_string(level+1));
3107
+
3108
+ return s;
3109
+
3110
+ }
3111
+ };
3112
+
3113
+ template <class Json,class JsonReference>
3114
+ class expression : public expression_base<Json,JsonReference>
3115
+ {
3116
+ public:
3117
+ using path_value_pair_type = path_value_pair<Json,JsonReference>;
3118
+ using value_type = Json;
3119
+ using reference = typename path_value_pair_type::reference;
3120
+ using pointer = typename path_value_pair_type::value_pointer;
3121
+ using const_pointer = const value_type*;
3122
+ using char_type = typename Json::char_type;
3123
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
3124
+ using string_view_type = typename Json::string_view_type;
3125
+ using path_value_pair_less_type = path_value_pair_less<Json,reference>;
3126
+ using path_value_pair_equal_type = path_value_pair_equal<Json,reference>;
3127
+ using parameter_type = parameter<Json>;
3128
+ using token_type = token<Json,reference>;
3129
+ using reference_arg_type = typename std::conditional<std::is_const<typename std::remove_reference<reference>::type>::value,
3130
+ const_reference_arg_t,reference_arg_t>::type;
3131
+ using json_location_node_type = json_location_node<char_type>;
3132
+ using stack_item_type = value_or_pointer<Json,JsonReference>;
3133
+ private:
3134
+ std::vector<token_type> token_list_;
3135
+ public:
3136
+
3137
+ expression()
3138
+ {
3139
+ }
3140
+
3141
+ expression(expression&& expr)
3142
+ : token_list_(std::move(expr.token_list_))
3143
+ {
3144
+ }
3145
+
3146
+ expression(std::vector<token_type>&& token_stack)
3147
+ : token_list_(std::move(token_stack))
3148
+ {
3149
+ }
3150
+
3151
+ expression& operator=(expression&& expr) = default;
3152
+
3153
+ value_type evaluate(dynamic_resources<Json,reference>& resources,
3154
+ reference root,
3155
+ reference current,
3156
+ result_options options,
3157
+ std::error_code& ec) const override
3158
+ {
3159
+ std::vector<stack_item_type> stack;
3160
+ std::vector<parameter_type> arg_stack;
3161
+
3162
+ //std::cout << "EVALUATE TOKENS\n";
3163
+ //for (auto& tok : token_list_)
3164
+ //{
3165
+ // std::cout << tok.to_string() << "\n";
3166
+ //}
3167
+ //std::cout << "\n";
3168
+
3169
+ if (!token_list_.empty())
3170
+ {
3171
+ for (auto& tok : token_list_)
3172
+ {
3173
+ //std::cout << "Token: " << tok.to_string() << "\n";
3174
+ switch (tok.token_kind())
3175
+ {
3176
+ case jsonpath_token_kind::literal:
3177
+ {
3178
+ stack.emplace_back(std::addressof(tok.get_value(reference_arg_type(), resources)));
3179
+ break;
3180
+ }
3181
+ case jsonpath_token_kind::unary_operator:
3182
+ {
3183
+ JSONCONS_ASSERT(stack.size() >= 1);
3184
+ auto item = std::move(stack.back());
3185
+ stack.pop_back();
3186
+
3187
+ auto val = tok.unary_operator_->evaluate(item.value(), ec);
3188
+ stack.emplace_back(std::move(val));
3189
+ break;
3190
+ }
3191
+ case jsonpath_token_kind::binary_operator:
3192
+ {
3193
+ //std::cout << "binary operator: " << stack.size() << "\n";
3194
+ JSONCONS_ASSERT(stack.size() >= 2);
3195
+ auto rhs = std::move(stack.back());
3196
+ //std::cout << "rhs: " << *rhs << "\n";
3197
+ stack.pop_back();
3198
+ auto lhs = std::move(stack.back());
3199
+ //std::cout << "lhs: " << *lhs << "\n";
3200
+ stack.pop_back();
3201
+
3202
+ auto val = tok.binary_operator_->evaluate(lhs.value(), rhs.value(), ec);
3203
+ //std::cout << "Evaluate binary expression: " << r << "\n";
3204
+ stack.emplace_back(std::move(val));
3205
+ break;
3206
+ }
3207
+ case jsonpath_token_kind::root_node:
3208
+ //std::cout << "root: " << root << "\n";
3209
+ stack.emplace_back(std::addressof(root));
3210
+ break;
3211
+ case jsonpath_token_kind::current_node:
3212
+ //std::cout << "current: " << current << "\n";
3213
+ stack.emplace_back(std::addressof(current));
3214
+ break;
3215
+ case jsonpath_token_kind::argument:
3216
+ JSONCONS_ASSERT(!stack.empty());
3217
+ //std::cout << "argument stack items " << stack.size() << "\n";
3218
+ //for (auto& item : stack)
3219
+ //{
3220
+ // std::cout << *item.to_pointer(resources) << "\n";
3221
+ //}
3222
+ //std::cout << "\n";
3223
+ arg_stack.emplace_back(std::move(stack.back()));
3224
+ //for (auto& item : arg_stack)
3225
+ //{
3226
+ // std::cout << *item << "\n";
3227
+ //}
3228
+ //std::cout << "\n";
3229
+ stack.pop_back();
3230
+ break;
3231
+ case jsonpath_token_kind::function:
3232
+ {
3233
+ if (tok.function_->arity() && *(tok.function_->arity()) != arg_stack.size())
3234
+ {
3235
+ ec = jsonpath_errc::invalid_arity;
3236
+ return Json::null();
3237
+ }
3238
+ //std::cout << "function arg stack:\n";
3239
+ //for (auto& item : arg_stack)
3240
+ //{
3241
+ // std::cout << *item << "\n";
3242
+ //}
3243
+ //std::cout << "\n";
3244
+
3245
+ value_type val = tok.function_->evaluate(arg_stack, ec);
3246
+ if (ec)
3247
+ {
3248
+ return Json::null();
3249
+ }
3250
+ //std::cout << "function result: " << val << "\n";
3251
+ arg_stack.clear();
3252
+ stack.emplace_back(std::move(val));
3253
+ break;
3254
+ }
3255
+ case jsonpath_token_kind::expression:
3256
+ {
3257
+ value_type val = tok.expression_->evaluate(resources, root, current, options, ec);
3258
+ stack.emplace_back(std::move(val));
3259
+ break;
3260
+ }
3261
+ case jsonpath_token_kind::selector:
3262
+ {
3263
+ JSONCONS_ASSERT(!stack.empty());
3264
+ auto item = std::move(stack.back());
3265
+ //for (auto& item : stack)
3266
+ //{
3267
+ //std::cout << "selector stack input:\n";
3268
+ //switch (item.tag)
3269
+ //{
3270
+ // case node_set_tag::single:
3271
+ // std::cout << "single: " << *(item.node.ptr) << "\n";
3272
+ // break;
3273
+ // case node_set_tag::multi:
3274
+ // for (auto& node : stack.back().ptr().nodes)
3275
+ // {
3276
+ // std::cout << "multi: " << *node.ptr << "\n";
3277
+ // }
3278
+ // break;
3279
+ // default:
3280
+ // break;
3281
+ //}
3282
+ //std::cout << "\n";
3283
+ //}
3284
+ //std::cout << "selector item: " << *ptr << "\n";
3285
+
3286
+ reference val = tok.selector_->evaluate(resources, root, resources.current_path_node(), item.value(), options, ec);
3287
+
3288
+ stack.pop_back();
3289
+ stack.emplace_back(stack_item_type(std::addressof(val)));
3290
+ break;
3291
+ }
3292
+ default:
3293
+ break;
3294
+ }
3295
+ }
3296
+ }
3297
+
3298
+ //if (stack.size() != 1)
3299
+ //{
3300
+ // std::cout << "Stack size: " << stack.size() << "\n";
3301
+ //}
3302
+ return stack.empty() ? Json::null() : stack.back().value();
3303
+ }
3304
+
3305
+ std::string to_string(int level) const override
3306
+ {
3307
+ std::string s;
3308
+ if (level > 0)
3309
+ {
3310
+ s.append("\n");
3311
+ s.append(level*2, ' ');
3312
+ }
3313
+ s.append("expression ");
3314
+ for (const auto& item : token_list_)
3315
+ {
3316
+ s.append(item.to_string(level+1));
3317
+ }
3318
+
3319
+ return s;
3320
+
3321
+ }
3322
+ private:
3323
+ };
3324
+
3325
+ } // namespace detail
3326
+ } // namespace jsonpath
3327
+ } // namespace jsoncons
3328
+
3329
+ #endif // JSONCONS_JSONPATH_JSONPATH_EXPRESSION_HPP