🔨 removed a logic error and improved coverage
This commit is contained in:
		
							parent
							
								
									922f7a3d0e
								
							
						
					
					
						commit
						8c7f46f7d0
					
				
					 4 changed files with 156 additions and 53 deletions
				
			
		| 
						 | 
				
			
			@ -594,7 +594,7 @@ class parser
 | 
			
		|||
                get_token();
 | 
			
		||||
 | 
			
		||||
                // closing } -> we are done
 | 
			
		||||
                if (last_token == token_type::end_object)
 | 
			
		||||
                if (JSON_UNLIKELY(last_token == token_type::end_object))
 | 
			
		||||
                {
 | 
			
		||||
                    return sax->end_object();
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -603,7 +603,12 @@ class parser
 | 
			
		|||
                while (true)
 | 
			
		||||
                {
 | 
			
		||||
                    // parse key
 | 
			
		||||
                    if (last_token != token_type::value_string)
 | 
			
		||||
                    if (JSON_UNLIKELY(last_token != token_type::value_string))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        if (not sax->key(m_lexer.move_string()))
 | 
			
		||||
                        {
 | 
			
		||||
| 
						 | 
				
			
			@ -613,9 +618,10 @@ class parser
 | 
			
		|||
 | 
			
		||||
                    // parse separator (:)
 | 
			
		||||
                    get_token();
 | 
			
		||||
                    if (last_token != token_type::name_separator)
 | 
			
		||||
                    if (JSON_UNLIKELY(last_token != token_type::name_separator))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // parse value
 | 
			
		||||
| 
						 | 
				
			
			@ -634,13 +640,14 @@ class parser
 | 
			
		|||
                    }
 | 
			
		||||
 | 
			
		||||
                    // closing }
 | 
			
		||||
                    if (last_token == token_type::end_object)
 | 
			
		||||
                    if (JSON_LIKELY(last_token == token_type::end_object))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->end_object();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -679,13 +686,14 @@ class parser
 | 
			
		|||
                    }
 | 
			
		||||
 | 
			
		||||
                    // closing ]
 | 
			
		||||
                    if (last_token == token_type::end_array)
 | 
			
		||||
                    if (JSON_LIKELY(last_token == token_type::end_array))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->end_array();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -696,7 +704,8 @@ class parser
 | 
			
		|||
 | 
			
		||||
                if (JSON_UNLIKELY(not std::isfinite(res)))
 | 
			
		||||
                {
 | 
			
		||||
                    return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                    return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                            m_lexer.get_token_string());
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -736,7 +745,8 @@ class parser
 | 
			
		|||
 | 
			
		||||
            default: // the last token was unexpected
 | 
			
		||||
            {
 | 
			
		||||
                return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                        m_lexer.get_token_string());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1054,8 +1054,6 @@ class basic_json
 | 
			
		|||
    */
 | 
			
		||||
    using parse_event_t = typename parser::parse_event_t;
 | 
			
		||||
 | 
			
		||||
    using SAX = typename parser::SAX;
 | 
			
		||||
 | 
			
		||||
    /*!
 | 
			
		||||
    @brief per-element parser callback type
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1107,6 +1105,7 @@ class basic_json
 | 
			
		|||
    */
 | 
			
		||||
    using parser_callback_t = typename parser::parser_callback_t;
 | 
			
		||||
 | 
			
		||||
    using SAX = typename parser::SAX;
 | 
			
		||||
 | 
			
		||||
    //////////////////
 | 
			
		||||
    // constructors //
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3717,7 +3717,7 @@ class parser
 | 
			
		|||
                get_token();
 | 
			
		||||
 | 
			
		||||
                // closing } -> we are done
 | 
			
		||||
                if (last_token == token_type::end_object)
 | 
			
		||||
                if (JSON_UNLIKELY(last_token == token_type::end_object))
 | 
			
		||||
                {
 | 
			
		||||
                    return sax->end_object();
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -3726,7 +3726,12 @@ class parser
 | 
			
		|||
                while (true)
 | 
			
		||||
                {
 | 
			
		||||
                    // parse key
 | 
			
		||||
                    if (last_token != token_type::value_string)
 | 
			
		||||
                    if (JSON_UNLIKELY(last_token != token_type::value_string))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        if (not sax->key(m_lexer.move_string()))
 | 
			
		||||
                        {
 | 
			
		||||
| 
						 | 
				
			
			@ -3736,9 +3741,10 @@ class parser
 | 
			
		|||
 | 
			
		||||
                    // parse separator (:)
 | 
			
		||||
                    get_token();
 | 
			
		||||
                    if (last_token != token_type::name_separator)
 | 
			
		||||
                    if (JSON_UNLIKELY(last_token != token_type::name_separator))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // parse value
 | 
			
		||||
| 
						 | 
				
			
			@ -3757,13 +3763,14 @@ class parser
 | 
			
		|||
                    }
 | 
			
		||||
 | 
			
		||||
                    // closing }
 | 
			
		||||
                    if (last_token == token_type::end_object)
 | 
			
		||||
                    if (JSON_LIKELY(last_token == token_type::end_object))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->end_object();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3802,13 +3809,14 @@ class parser
 | 
			
		|||
                    }
 | 
			
		||||
 | 
			
		||||
                    // closing ]
 | 
			
		||||
                    if (last_token == token_type::end_array)
 | 
			
		||||
                    if (JSON_LIKELY(last_token == token_type::end_array))
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->end_array();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                        return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                                m_lexer.get_token_string());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3819,7 +3827,8 @@ class parser
 | 
			
		|||
 | 
			
		||||
                if (JSON_UNLIKELY(not std::isfinite(res)))
 | 
			
		||||
                {
 | 
			
		||||
                    return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                    return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                            m_lexer.get_token_string());
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -3859,7 +3868,8 @@ class parser
 | 
			
		|||
 | 
			
		||||
            default: // the last token was unexpected
 | 
			
		||||
            {
 | 
			
		||||
                return sax->parse_error(m_lexer.get_position(), m_lexer.get_token_string());
 | 
			
		||||
                return sax->parse_error(m_lexer.get_position(),
 | 
			
		||||
                                        m_lexer.get_token_string());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -10875,8 +10885,6 @@ class basic_json
 | 
			
		|||
    */
 | 
			
		||||
    using parse_event_t = typename parser::parse_event_t;
 | 
			
		||||
 | 
			
		||||
    using SAX = typename parser::SAX;
 | 
			
		||||
 | 
			
		||||
    /*!
 | 
			
		||||
    @brief per-element parser callback type
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10928,6 +10936,7 @@ class basic_json
 | 
			
		|||
    */
 | 
			
		||||
    using parser_callback_t = typename parser::parser_callback_t;
 | 
			
		||||
 | 
			
		||||
    using SAX = typename parser::SAX;
 | 
			
		||||
 | 
			
		||||
    //////////////////
 | 
			
		||||
    // constructors //
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,9 +34,8 @@ using nlohmann::json;
 | 
			
		|||
#include <iostream>
 | 
			
		||||
#include <valarray>
 | 
			
		||||
 | 
			
		||||
class SaxEventLogger : public nlohmann::json::SAX
 | 
			
		||||
struct SaxEventLogger : public nlohmann::json::SAX
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    bool null() override
 | 
			
		||||
    {
 | 
			
		||||
        events.push_back("null()");
 | 
			
		||||
| 
						 | 
				
			
			@ -132,6 +131,47 @@ class SaxEventLogger : public nlohmann::json::SAX
 | 
			
		|||
    std::vector<std::string> events;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
 | 
			
		||||
{
 | 
			
		||||
    bool start_object(std::size_t elements) override
 | 
			
		||||
    {
 | 
			
		||||
        if (elements == -1)
 | 
			
		||||
        {
 | 
			
		||||
            events.push_back("start_object()");
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            events.push_back("start_object(" + std::to_string(elements) + ")");
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SaxEventLoggerExitAfterKey : public SaxEventLogger
 | 
			
		||||
{
 | 
			
		||||
    bool key(const std::string& val) override
 | 
			
		||||
    {
 | 
			
		||||
        events.push_back("key(" + val + ")");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
 | 
			
		||||
{
 | 
			
		||||
    bool start_array(std::size_t elements) override
 | 
			
		||||
    {
 | 
			
		||||
        if (elements == -1)
 | 
			
		||||
        {
 | 
			
		||||
            events.push_back("start_array()");
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            events.push_back("start_array(" + std::to_string(elements) + ")");
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
TEST_CASE("deserialization")
 | 
			
		||||
{
 | 
			
		||||
    SECTION("successful deserialization")
 | 
			
		||||
| 
						 | 
				
			
			@ -148,13 +188,13 @@ TEST_CASE("deserialization")
 | 
			
		|||
 | 
			
		||||
            SaxEventLogger l;
 | 
			
		||||
            CHECK(json::sax_parse(ss3, &l));
 | 
			
		||||
            CHECK(l.events.size() == 10);
 | 
			
		||||
            CHECK(l.events.size() == 11);
 | 
			
		||||
            CHECK(l.events == std::vector<std::string>(
 | 
			
		||||
            {
 | 
			
		||||
                "start_array()", "string(foo)",
 | 
			
		||||
                "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
 | 
			
		||||
                "boolean(false)", "start_object()",
 | 
			
		||||
                "number_unsigned(1)", "end_object()", "end_array()"
 | 
			
		||||
                "start_array()", "string(foo)", "number_unsigned(1)",
 | 
			
		||||
                "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
 | 
			
		||||
                "start_object()", "key(one)", "number_unsigned(1)",
 | 
			
		||||
                "end_object()", "end_array()"
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -167,13 +207,13 @@ TEST_CASE("deserialization")
 | 
			
		|||
 | 
			
		||||
            SaxEventLogger l;
 | 
			
		||||
            CHECK(json::sax_parse(s, &l));
 | 
			
		||||
            CHECK(l.events.size() == 10);
 | 
			
		||||
            CHECK(l.events.size() == 11);
 | 
			
		||||
            CHECK(l.events == std::vector<std::string>(
 | 
			
		||||
            {
 | 
			
		||||
                "start_array()", "string(foo)",
 | 
			
		||||
                "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
 | 
			
		||||
                "boolean(false)", "start_object()",
 | 
			
		||||
                "number_unsigned(1)", "end_object()", "end_array()"
 | 
			
		||||
                "start_array()", "string(foo)", "number_unsigned(1)",
 | 
			
		||||
                "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
 | 
			
		||||
                "start_object()", "key(one)", "number_unsigned(1)",
 | 
			
		||||
                "end_object()", "end_array()"
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -186,13 +226,13 @@ TEST_CASE("deserialization")
 | 
			
		|||
 | 
			
		||||
            SaxEventLogger l;
 | 
			
		||||
            CHECK(json::sax_parse(s, &l));
 | 
			
		||||
            CHECK(l.events.size() == 10);
 | 
			
		||||
            CHECK(l.events.size() == 11);
 | 
			
		||||
            CHECK(l.events == std::vector<std::string>(
 | 
			
		||||
            {
 | 
			
		||||
                "start_array()", "string(foo)",
 | 
			
		||||
                "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
 | 
			
		||||
                "boolean(false)", "start_object()",
 | 
			
		||||
                "number_unsigned(1)", "end_object()", "end_array()"
 | 
			
		||||
                "start_array()", "string(foo)", "number_unsigned(1)",
 | 
			
		||||
                "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
 | 
			
		||||
                "start_object()", "key(one)", "number_unsigned(1)",
 | 
			
		||||
                "end_object()", "end_array()"
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -241,13 +281,13 @@ TEST_CASE("deserialization")
 | 
			
		|||
 | 
			
		||||
            SaxEventLogger l;
 | 
			
		||||
            CHECK(not json::sax_parse(ss5, &l));
 | 
			
		||||
            CHECK(l.events.size() == 10);
 | 
			
		||||
            CHECK(l.events.size() == 11);
 | 
			
		||||
            CHECK(l.events == std::vector<std::string>(
 | 
			
		||||
            {
 | 
			
		||||
                "start_array()", "string(foo)",
 | 
			
		||||
                "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
 | 
			
		||||
                "boolean(false)", "start_object()",
 | 
			
		||||
                "number_unsigned(1)", "end_object()", "parse_error(29)"
 | 
			
		||||
                "start_array()", "string(foo)", "number_unsigned(1)",
 | 
			
		||||
                "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
 | 
			
		||||
                "start_object()", "key(one)", "number_unsigned(1)",
 | 
			
		||||
                "end_object()", "parse_error(29)"
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -265,13 +305,13 @@ TEST_CASE("deserialization")
 | 
			
		|||
 | 
			
		||||
            SaxEventLogger l;
 | 
			
		||||
            CHECK(not json::sax_parse(s, &l));
 | 
			
		||||
            CHECK(l.events.size() == 10);
 | 
			
		||||
            CHECK(l.events.size() == 11);
 | 
			
		||||
            CHECK(l.events == std::vector<std::string>(
 | 
			
		||||
            {
 | 
			
		||||
                "start_array()", "string(foo)",
 | 
			
		||||
                "number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
 | 
			
		||||
                "boolean(false)", "start_object()",
 | 
			
		||||
                "number_unsigned(1)", "end_object()", "parse_error(29)"
 | 
			
		||||
                "start_array()", "string(foo)", "number_unsigned(1)",
 | 
			
		||||
                "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
 | 
			
		||||
                "start_object()", "key(one)", "number_unsigned(1)",
 | 
			
		||||
                "end_object()", "parse_error(29)"
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -746,10 +786,10 @@ TEST_CASE("deserialization")
 | 
			
		|||
 | 
			
		||||
                SaxEventLogger l;
 | 
			
		||||
                CHECK(not json::sax_parse(std::begin(v), std::end(v), &l));
 | 
			
		||||
                CHECK(l.events.size() == 3);
 | 
			
		||||
                CHECK(l.events.size() == 4);
 | 
			
		||||
                CHECK(l.events == std::vector<std::string>(
 | 
			
		||||
                {
 | 
			
		||||
                    "start_object()", "number_unsigned(11)",
 | 
			
		||||
                    "start_object()", "key()", "number_unsigned(11)",
 | 
			
		||||
                    "parse_error(7)"
 | 
			
		||||
                }));
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -912,4 +952,49 @@ TEST_CASE("deserialization")
 | 
			
		|||
            CHECK(j == 456);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SECTION("SAX and early abort")
 | 
			
		||||
    {
 | 
			
		||||
        std::string s = "[1, [\"string\", 43.12], null, {\"key1\": true, \"key2\": false}]";
 | 
			
		||||
 | 
			
		||||
        SaxEventLogger default_logger;
 | 
			
		||||
        SaxEventLoggerExitAfterStartObject exit_after_start_object;
 | 
			
		||||
        SaxEventLoggerExitAfterKey exit_after_key;
 | 
			
		||||
        SaxEventLoggerExitAfterStartArray exit_after_start_array;
 | 
			
		||||
 | 
			
		||||
        json::sax_parse(s, &default_logger);
 | 
			
		||||
        CHECK(default_logger.events.size() == 14);
 | 
			
		||||
        CHECK(default_logger.events == std::vector<std::string>(
 | 
			
		||||
        {
 | 
			
		||||
            "start_array()", "number_unsigned(1)", "start_array()",
 | 
			
		||||
            "string(string)", "number_float(43.12)", "end_array()", "null()",
 | 
			
		||||
            "start_object()", "key(key1)", "boolean(true)", "key(key2)",
 | 
			
		||||
            "boolean(false)", "end_object()", "end_array()"
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        json::sax_parse(s, &exit_after_start_object);
 | 
			
		||||
        CHECK(exit_after_start_object.events.size() == 8);
 | 
			
		||||
        CHECK(exit_after_start_object.events == std::vector<std::string>(
 | 
			
		||||
        {
 | 
			
		||||
            "start_array()", "number_unsigned(1)", "start_array()",
 | 
			
		||||
            "string(string)", "number_float(43.12)", "end_array()", "null()",
 | 
			
		||||
            "start_object()"
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        json::sax_parse(s, &exit_after_key);
 | 
			
		||||
        CHECK(exit_after_key.events.size() == 9);
 | 
			
		||||
        CHECK(exit_after_key.events == std::vector<std::string>(
 | 
			
		||||
        {
 | 
			
		||||
            "start_array()", "number_unsigned(1)", "start_array()",
 | 
			
		||||
            "string(string)", "number_float(43.12)", "end_array()", "null()",
 | 
			
		||||
            "start_object()", "key(key1)"
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        json::sax_parse(s, &exit_after_start_array);
 | 
			
		||||
        CHECK(exit_after_start_array.events.size() == 1);
 | 
			
		||||
        CHECK(exit_after_start_array.events == std::vector<std::string>(
 | 
			
		||||
        {
 | 
			
		||||
            "start_array()"
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue