jsoncons 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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