// Copyright 2018 Daniel Parker // Distributed under the Boost license, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See https://github.com/danielaparker/jsoncons for latest version #ifndef JSONCONS_STAJ_CURSOR_HPP #define JSONCONS_STAJ_CURSOR_HPP #include // std::allocator #include #include #include #include #include // std::enable_if #include // std::array #include // std::function #include #include #include #include #include #include #include #include #include #include namespace jsoncons { enum class staj_event_type { begin_array, end_array, begin_object, end_object, key, string_value, byte_string_value, null_value, bool_value, int64_value, uint64_value, half_value, double_value #if !defined(JSONCONS_NO_DEPRECATED) ,name = key #endif }; template std::basic_ostream& operator<<(std::basic_ostream& os, staj_event_type tag) { static constexpr const CharT* begin_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_array"); static constexpr const CharT* end_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_array"); static constexpr const CharT* begin_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_object"); static constexpr const CharT* end_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_object"); static constexpr const CharT* key_name = JSONCONS_CSTRING_CONSTANT(CharT, "key"); static constexpr const CharT* string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "string_value"); static constexpr const CharT* byte_string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string_value"); static constexpr const CharT* null_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "null_value"); static constexpr const CharT* bool_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "bool_value"); static constexpr const CharT* uint64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "uint64_value"); static constexpr const CharT* int64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "int64_value"); static constexpr const CharT* half_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "half_value"); static constexpr const CharT* double_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "double_value"); switch (tag) { case staj_event_type::begin_array: { os << begin_array_name; break; } case staj_event_type::end_array: { os << end_array_name; break; } case staj_event_type::begin_object: { os << begin_object_name; break; } case staj_event_type::end_object: { os << end_object_name; break; } case staj_event_type::key: { os << key_name; break; } case staj_event_type::string_value: { os << string_value_name; break; } case staj_event_type::byte_string_value: { os << byte_string_value_name; break; } case staj_event_type::null_value: { os << null_value_name; break; } case staj_event_type::bool_value: { os << bool_value_name; break; } case staj_event_type::int64_value: { os << int64_value_name; break; } case staj_event_type::uint64_value: { os << uint64_value_name; break; } case staj_event_type::half_value: { os << half_value_name; break; } case staj_event_type::double_value: { os << double_value_name; break; } } return os; } template class basic_staj_event { staj_event_type event_type_; semantic_tag tag_; uint64_t ext_tag_; union { bool bool_value_; int64_t int64_value_; uint64_t uint64_value_; uint16_t half_value_; double double_value_; const CharT* string_data_; const uint8_t* byte_string_data_; } value_; std::size_t length_; public: using string_view_type = jsoncons::basic_string_view; basic_staj_event(staj_event_type event_type, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), ext_tag_(0), value_(), length_(0) { } basic_staj_event(staj_event_type event_type, std::size_t length, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), ext_tag_(0), value_(), length_(length) { } basic_staj_event(null_type, semantic_tag tag) : event_type_(staj_event_type::null_value), tag_(tag), ext_tag_(0), value_(), length_(0) { } basic_staj_event(bool value, semantic_tag tag) : event_type_(staj_event_type::bool_value), tag_(tag), ext_tag_(0), length_(0) { value_.bool_value_ = value; } basic_staj_event(int64_t value, semantic_tag tag) : event_type_(staj_event_type::int64_value), tag_(tag), ext_tag_(0), length_(0) { value_.int64_value_ = value; } basic_staj_event(uint64_t value, semantic_tag tag) : event_type_(staj_event_type::uint64_value), tag_(tag), ext_tag_(0), length_(0) { value_.uint64_value_ = value; } basic_staj_event(half_arg_t, uint16_t value, semantic_tag tag) : event_type_(staj_event_type::half_value), tag_(tag), ext_tag_(0), length_(0) { value_.half_value_ = value; } basic_staj_event(double value, semantic_tag tag) : event_type_(staj_event_type::double_value), tag_(tag), ext_tag_(0), length_(0) { value_.double_value_ = value; } basic_staj_event(const string_view_type& s, staj_event_type event_type, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), ext_tag_(0), length_(s.length()) { value_.string_data_ = s.data(); } basic_staj_event(const byte_string_view& s, staj_event_type event_type, semantic_tag tag = semantic_tag::none) : event_type_(event_type), tag_(tag), ext_tag_(0), length_(s.size()) { value_.byte_string_data_ = s.data(); } basic_staj_event(const byte_string_view& s, staj_event_type event_type, uint64_t ext_tag) : event_type_(event_type), tag_(semantic_tag::ext), ext_tag_(ext_tag), length_(s.size()) { value_.byte_string_data_ = s.data(); } std::size_t size() const { return length_; } template T get() const { std::error_code ec; T val = get(ec); if (ec) { JSONCONS_THROW(ser_error(ec)); } return val; } template typename std::enable_if::value && std::is_same::value, T>::type get(std::error_code& ec) const { converter conv; switch (event_type_) { case staj_event_type::key: case staj_event_type::string_value: return conv.from(jsoncons::basic_string_view(value_.string_data_, length_), tag(), ec); case staj_event_type::byte_string_value: { return conv.from(byte_string_view(value_.byte_string_data_,length_), tag(), ec); } case staj_event_type::uint64_value: { return conv.from(value_.uint64_value_, tag(), ec); } case staj_event_type::int64_value: { return conv.from(value_.int64_value_, tag(), ec); } case staj_event_type::half_value: { return conv.from(half_arg, value_.half_value_, tag(), ec); } case staj_event_type::double_value: { return conv.from(value_.double_value_, tag(), ec); } case staj_event_type::bool_value: { return conv.from(value_.bool_value_,tag(),ec); } case staj_event_type::null_value: { return conv.from(null_type(),tag(),ec); } default: { ec = conv_errc::not_string; return T{}; } } } template typename std::enable_if::value && std::is_same::value, T>::type get(std::error_code& ec) const { T s; switch (event_type_) { case staj_event_type::key: case staj_event_type::string_value: s = T(value_.string_data_, length_); break; default: ec = conv_errc::not_string_view; break; } return s; } template typename std::enable_if::value, T>::type get(std::error_code& ec) const { T s; switch (event_type_) { case staj_event_type::byte_string_value: s = T(value_.byte_string_data_, length_); break; default: ec = conv_errc::not_byte_string_view; break; } return s; } template typename std::enable_if::value && std::is_same::value,T>::type get(std::error_code& ec) const { converter conv; switch (event_type_) { case staj_event_type::byte_string_value: return conv.from(byte_string_view(value_.byte_string_data_, length_), tag(), ec); case staj_event_type::string_value: return conv.from(jsoncons::basic_string_view(value_.string_data_, length_), tag(), ec); default: ec = conv_errc::not_byte_string; return T{}; } } template typename std::enable_if::value, IntegerType>::type get(std::error_code& ec) const { switch (event_type_) { case staj_event_type::string_value: { IntegerType val; auto result = jsoncons::detail::to_integer(value_.string_data_, length_, val); if (!result) { ec = conv_errc::not_integer; return IntegerType(); } return val; } case staj_event_type::half_value: return static_cast(value_.half_value_); case staj_event_type::double_value: return static_cast(value_.double_value_); case staj_event_type::int64_value: return static_cast(value_.int64_value_); case staj_event_type::uint64_value: return static_cast(value_.uint64_value_); case staj_event_type::bool_value: return static_cast(value_.bool_value_ ? 1 : 0); default: ec = conv_errc::not_integer; return IntegerType(); } } template typename std::enable_if::value, T>::type get(std::error_code& ec) const { return static_cast(as_double(ec)); } template typename std::enable_if::value, T>::type get(std::error_code& ec) const { return as_bool(ec); } #if !defined(JSONCONS_NO_DEPRECATED) template JSONCONS_DEPRECATED_MSG("Instead, use get()") T as() const { return get(); } semantic_tag get_semantic_tag() const noexcept { return tag_; } #endif staj_event_type event_type() const noexcept { return event_type_; } semantic_tag tag() const noexcept { return tag_; } uint64_t ext_tag() const noexcept { return ext_tag_; } private: double as_double(std::error_code& ec) const { switch (event_type_) { case staj_event_type::key: case staj_event_type::string_value: { jsoncons::detail::chars_to f; return f(value_.string_data_, length_); } case staj_event_type::double_value: return value_.double_value_; case staj_event_type::int64_value: return static_cast(value_.int64_value_); case staj_event_type::uint64_value: return static_cast(value_.uint64_value_); case staj_event_type::half_value: { double x = binary::decode_half(value_.half_value_); return static_cast(x); } default: ec = conv_errc::not_double; return double(); } } bool as_bool(std::error_code& ec) const { switch (event_type_) { case staj_event_type::bool_value: return value_.bool_value_; case staj_event_type::double_value: return value_.double_value_ != 0.0; case staj_event_type::int64_value: return value_.int64_value_ != 0; case staj_event_type::uint64_value: return value_.uint64_value_ != 0; default: ec = conv_errc::not_bool; return bool(); } } }; // basic_staj_visitor enum class staj_cursor_state { typed_array = 1, multi_dim, shape }; template class basic_staj_visitor : public basic_json_visitor { using super_type = basic_json_visitor; public: using char_type = CharT; using typename super_type::string_view_type; private: std::function&, const ser_context&)> pred_; basic_staj_event event_; staj_cursor_state state_; typed_array_view data_; jsoncons::span shape_; std::size_t index_; public: basic_staj_visitor() : pred_(accept), event_(staj_event_type::null_value), state_(), data_(), shape_(), index_(0) { } basic_staj_visitor(std::function&, const ser_context&)> pred) : pred_(pred), event_(staj_event_type::null_value), state_(), data_(), shape_(), index_(0) { } void reset() { event_ = staj_event_type::null_value; state_ = {}; data_ = {}; shape_ = {}; index_ = 0; } const basic_staj_event& event() const { return event_; } bool in_available() const { return state_ != staj_cursor_state(); } void send_available(std::error_code& ec) { switch (state_) { case staj_cursor_state::typed_array: advance_typed_array(ec); break; case staj_cursor_state::multi_dim: case staj_cursor_state::shape: advance_multi_dim(ec); break; default: break; } } bool is_typed_array() const { return data_.type() != typed_array_type(); } staj_cursor_state state() const { return state_; } void advance_typed_array(std::error_code& ec) { if (is_typed_array()) { if (index_ < data_.size()) { switch (data_.type()) { case typed_array_type::uint8_value: { this->uint64_value(data_.data(uint8_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint16_value: { this->uint64_value(data_.data(uint16_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint32_value: { this->uint64_value(data_.data(uint32_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::uint64_value: { this->uint64_value(data_.data(uint64_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int8_value: { this->int64_value(data_.data(int8_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int16_value: { this->int64_value(data_.data(int16_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int32_value: { this->int64_value(data_.data(int32_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::int64_value: { this->int64_value(data_.data(int64_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::half_value: { this->half_value(data_.data(half_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::float_value: { this->double_value(data_.data(float_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } case typed_array_type::double_value: { this->double_value(data_.data(double_array_arg)[index_], semantic_tag::none, ser_context(), ec); break; } default: break; } ++index_; } else { this->end_array(); state_ = staj_cursor_state(); data_ = typed_array_view(); index_ = 0; } } } void advance_multi_dim(std::error_code& ec) { if (shape_.size() != 0) { if (state_ == staj_cursor_state::multi_dim) { this->begin_array(shape_.size(), semantic_tag::none, ser_context(), ec); state_ = staj_cursor_state::shape; } else if (index_ < shape_.size()) { this->uint64_value(shape_[index_], semantic_tag::none, ser_context(), ec); ++index_; } else { state_ = staj_cursor_state(); this->end_array(ser_context(), ec); shape_ = jsoncons::span(); index_ = 0; } } } bool dump(basic_json_visitor& visitor, const ser_context& context, std::error_code& ec) { bool more = true; if (is_typed_array()) { if (index_ != 0) { more = staj_to_saj_event(event(), visitor, context, ec); while (more && is_typed_array()) { if (index_ < data_.size()) { switch (data_.type()) { case typed_array_type::uint8_value: { more = visitor.uint64_value(data_.data(uint8_array_arg)[index_]); break; } case typed_array_type::uint16_value: { more = visitor.uint64_value(data_.data(uint16_array_arg)[index_]); break; } case typed_array_type::uint32_value: { more = visitor.uint64_value(data_.data(uint32_array_arg)[index_]); break; } case typed_array_type::uint64_value: { more = visitor.uint64_value(data_.data(uint64_array_arg)[index_]); break; } case typed_array_type::int8_value: { more = visitor.int64_value(data_.data(int8_array_arg)[index_]); break; } case typed_array_type::int16_value: { more = visitor.int64_value(data_.data(int16_array_arg)[index_]); break; } case typed_array_type::int32_value: { more = visitor.int64_value(data_.data(int32_array_arg)[index_]); break; } case typed_array_type::int64_value: { more = visitor.int64_value(data_.data(int64_array_arg)[index_]); break; } case typed_array_type::float_value: { more = visitor.double_value(data_.data(float_array_arg)[index_]); break; } case typed_array_type::double_value: { more = visitor.double_value(data_.data(double_array_arg)[index_]); break; } default: break; } ++index_; } else { more = visitor.end_array(); state_ = staj_cursor_state(); data_ = typed_array_view(); index_ = 0; } } } else { switch (data_.type()) { case typed_array_type::uint8_value: { more = visitor.typed_array(data_.data(uint8_array_arg)); break; } case typed_array_type::uint16_value: { more = visitor.typed_array(data_.data(uint16_array_arg)); break; } case typed_array_type::uint32_value: { more = visitor.typed_array(data_.data(uint32_array_arg)); break; } case typed_array_type::uint64_value: { more = visitor.typed_array(data_.data(uint64_array_arg)); break; } case typed_array_type::int8_value: { more = visitor.typed_array(data_.data(int8_array_arg)); break; } case typed_array_type::int16_value: { more = visitor.typed_array(data_.data(int16_array_arg)); break; } case typed_array_type::int32_value: { more = visitor.typed_array(data_.data(int32_array_arg)); break; } case typed_array_type::int64_value: { more = visitor.typed_array(data_.data(int64_array_arg)); break; } case typed_array_type::float_value: { more = visitor.typed_array(data_.data(float_array_arg)); break; } case typed_array_type::double_value: { more = visitor.typed_array(data_.data(double_array_arg)); break; } default: break; } state_ = staj_cursor_state(); data_ = typed_array_view(); } } else { more = staj_to_saj_event(event(), visitor, context, ec); } return more; } private: static constexpr bool accept(const basic_staj_event&, const ser_context&) { return true; } bool visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_object, tag); return !pred_(event_, context); } bool visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_object, length, tag); return !pred_(event_, context); } bool visit_end_object(const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_object); return !pred_(event_, context); } bool visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_array, tag); return !pred_(event_, context); } bool visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_array, length, tag); return !pred_(event_, context); } bool visit_end_array(const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_array); return !pred_(event_, context); } bool visit_key(const string_view_type& name, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(name, staj_event_type::key); return !pred_(event_, context); } bool visit_null(semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::null_value, tag); return !pred_(event_, context); } bool visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(value, tag); return !pred_(event_, context); } bool visit_string(const string_view_type& s, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::string_value, tag); return !pred_(event_, context); } bool visit_byte_string(const byte_string_view& s, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, tag); return !pred_(event_, context); } bool visit_byte_string(const byte_string_view& s, uint64_t ext_tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, ext_tag); return !pred_(event_, context); } bool visit_uint64(uint64_t value, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(value, tag); return !pred_(event_, context); } bool visit_int64(int64_t value, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(value, tag); return !pred_(event_, context); } bool visit_half(uint16_t value, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(half_arg, value, tag); return !pred_(event_, context); } bool visit_double(double value, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(value, tag); return !pred_(event_, context); } bool visit_typed_array(const jsoncons::span& v, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(v.data(), v.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(half_arg_t, const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } bool visit_typed_array(const jsoncons::span& data, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::typed_array; data_ = typed_array_view(data.data(), data.size()); index_ = 0; return this->begin_array(tag, context, ec); } /* bool visit_typed_array(const jsoncons::span&, semantic_tag, const ser_context&, std::error_code&) override { return true; } */ bool visit_begin_multi_dim(const jsoncons::span& shape, semantic_tag tag, const ser_context& context, std::error_code& ec) override { state_ = staj_cursor_state::multi_dim; shape_ = shape; return this->begin_array(2, tag, context, ec); } bool visit_end_multi_dim(const ser_context& context, std::error_code& ec) override { return this->end_array(context, ec); } void visit_flush() override { } }; template bool staj_to_saj_event(const basic_staj_event& ev, basic_json_visitor& visitor, const ser_context& context, std::error_code& ec) { switch (ev.event_type()) { case staj_event_type::begin_array: return visitor.begin_array(ev.tag(), context); case staj_event_type::end_array: return visitor.end_array(context); case staj_event_type::begin_object: return visitor.begin_object(ev.tag(), context, ec); case staj_event_type::end_object: return visitor.end_object(context, ec); case staj_event_type::key: return visitor.key(ev.template get>(), context); case staj_event_type::string_value: return visitor.string_value(ev.template get>(), ev.tag(), context); case staj_event_type::byte_string_value: return visitor.byte_string_value(ev.template get(), ev.tag(), context); case staj_event_type::null_value: return visitor.null_value(ev.tag(), context); case staj_event_type::bool_value: return visitor.bool_value(ev.template get(), ev.tag(), context); case staj_event_type::int64_value: return visitor.int64_value(ev.template get(), ev.tag(), context); case staj_event_type::uint64_value: return visitor.uint64_value(ev.template get(), ev.tag(), context); case staj_event_type::half_value: return visitor.half_value(ev.template get(), ev.tag(), context); case staj_event_type::double_value: return visitor.double_value(ev.template get(), ev.tag(), context); default: return false; } } // basic_staj_cursor template class basic_staj_cursor { public: virtual ~basic_staj_cursor() noexcept = default; virtual void array_expected(std::error_code& ec) { if (!(current().event_type() == staj_event_type::begin_array || current().event_type() == staj_event_type::byte_string_value)) { ec = conv_errc::not_vector; } } virtual bool done() const = 0; virtual const basic_staj_event& current() const = 0; virtual void read_to(basic_json_visitor& visitor) = 0; virtual void read_to(basic_json_visitor& visitor, std::error_code& ec) = 0; virtual void next() = 0; virtual void next(std::error_code& ec) = 0; virtual const ser_context& context() const = 0; }; template class basic_staj_filter_view : basic_staj_cursor { basic_staj_cursor* cursor_; std::function&, const ser_context&)> pred_; public: basic_staj_filter_view(basic_staj_cursor& cursor, std::function&, const ser_context&)> pred) : cursor_(std::addressof(cursor)), pred_(pred) { while (!done() && !pred_(current(),context())) { cursor_->next(); } } bool done() const override { return cursor_->done(); } const basic_staj_event& current() const override { return cursor_->current(); } void read_to(basic_json_visitor& visitor) override { cursor_->read_to(visitor); } void read_to(basic_json_visitor& visitor, std::error_code& ec) override { cursor_->read_to(visitor, ec); } void next() override { cursor_->next(); while (!done() && !pred_(current(),context())) { cursor_->next(); } } void next(std::error_code& ec) override { cursor_->next(ec); while (!done() && !pred_(current(),context()) && !ec) { cursor_->next(ec); } } const ser_context& context() const override { return cursor_->context(); } friend basic_staj_filter_view operator|(basic_staj_filter_view& cursor, std::function&, const ser_context&)> pred) { return basic_staj_filter_view(cursor, pred); } }; using staj_event = basic_staj_event; using wstaj_event = basic_staj_event; using staj_cursor = basic_staj_cursor; using wstaj_cursor = basic_staj_cursor; using staj_filter_view = basic_staj_filter_view; using wstaj_filter_view = basic_staj_filter_view; #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use staj_event_type") typedef staj_event_type stream_event_type; template using basic_stream_event = basic_staj_event; template using basic_stream_reader = basic_staj_cursor; template using basic_staj_reader = basic_staj_cursor; JSONCONS_DEPRECATED_MSG("Instead, use staj_event") typedef basic_staj_event stream_event; JSONCONS_DEPRECATED_MSG("Instead, use wstaj_event") typedef basic_staj_event wstream_event; JSONCONS_DEPRECATED_MSG("Instead, use staj_cursor") typedef basic_staj_cursor stream_reader; JSONCONS_DEPRECATED_MSG("Instead, use wstaj_cursor") typedef basic_staj_cursor wstream_reader; JSONCONS_DEPRECATED_MSG("Instead, use staj_cursor") typedef basic_staj_cursor staj_reader; JSONCONS_DEPRECATED_MSG("Instead, use wstaj_cursor") typedef basic_staj_cursor wstaj_reader; #endif } #endif