237 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#pragma once
 | 
						|
 | 
						|
#include <exception> // exception
 | 
						|
#include <stdexcept> // runtime_error
 | 
						|
#include <string> // to_string
 | 
						|
#include <vector> // vector
 | 
						|
 | 
						|
#include <nlohmann/detail/value_t.hpp>
 | 
						|
#include <nlohmann/detail/string_escape.hpp>
 | 
						|
#include <nlohmann/detail/input/position_t.hpp>
 | 
						|
#include <nlohmann/detail/macro_scope.hpp>
 | 
						|
 | 
						|
namespace nlohmann
 | 
						|
{
 | 
						|
namespace detail
 | 
						|
{
 | 
						|
////////////////
 | 
						|
// exceptions //
 | 
						|
////////////////
 | 
						|
 | 
						|
/// @brief general exception of the @ref basic_json class
 | 
						|
/// @sa https://json.nlohmann.me/api/basic_json/exception/
 | 
						|
class exception : public std::exception
 | 
						|
{
 | 
						|
  public:
 | 
						|
    /// returns the explanatory string
 | 
						|
    const char* what() const noexcept override
 | 
						|
    {
 | 
						|
        return m.what();
 | 
						|
    }
 | 
						|
 | 
						|
    /// the id of the exception
 | 
						|
    const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
 | 
						|
 | 
						|
  protected:
 | 
						|
    JSON_HEDLEY_NON_NULL(3)
 | 
						|
    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
 | 
						|
 | 
						|
    static std::string name(const std::string& ename, int id_)
 | 
						|
    {
 | 
						|
        return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
 | 
						|
    }
 | 
						|
 | 
						|
    template<typename BasicJsonType>
 | 
						|
    static std::string diagnostics(const BasicJsonType& leaf_element)
 | 
						|
    {
 | 
						|
#if JSON_DIAGNOSTICS
 | 
						|
        std::vector<std::string> tokens;
 | 
						|
        for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
 | 
						|
        {
 | 
						|
            switch (current->m_parent->type())
 | 
						|
            {
 | 
						|
                case value_t::array:
 | 
						|
                {
 | 
						|
                    for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
 | 
						|
                    {
 | 
						|
                        if (¤t->m_parent->m_value.array->operator[](i) == current)
 | 
						|
                        {
 | 
						|
                            tokens.emplace_back(std::to_string(i));
 | 
						|
                            break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                case value_t::object:
 | 
						|
                {
 | 
						|
                    for (const auto& element : *current->m_parent->m_value.object)
 | 
						|
                    {
 | 
						|
                        if (&element.second == current)
 | 
						|
                        {
 | 
						|
                            tokens.emplace_back(element.first.c_str());
 | 
						|
                            break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                case value_t::null: // LCOV_EXCL_LINE
 | 
						|
                case value_t::string: // LCOV_EXCL_LINE
 | 
						|
                case value_t::boolean: // LCOV_EXCL_LINE
 | 
						|
                case value_t::number_integer: // LCOV_EXCL_LINE
 | 
						|
                case value_t::number_unsigned: // LCOV_EXCL_LINE
 | 
						|
                case value_t::number_float: // LCOV_EXCL_LINE
 | 
						|
                case value_t::binary: // LCOV_EXCL_LINE
 | 
						|
                case value_t::discarded: // LCOV_EXCL_LINE
 | 
						|
                default:   // LCOV_EXCL_LINE
 | 
						|
                    break; // LCOV_EXCL_LINE
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (tokens.empty())
 | 
						|
        {
 | 
						|
            return "";
 | 
						|
        }
 | 
						|
 | 
						|
        return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
 | 
						|
                                     [](const std::string & a, const std::string & b)
 | 
						|
        {
 | 
						|
            return a + "/" + detail::escape(b);
 | 
						|
        }) + ") ";
 | 
						|
#else
 | 
						|
        static_cast<void>(leaf_element);
 | 
						|
        return "";
 | 
						|
#endif
 | 
						|
    }
 | 
						|
 | 
						|
  private:
 | 
						|
    /// an exception object as storage for error messages
 | 
						|
    std::runtime_error m;
 | 
						|
};
 | 
						|
 | 
						|
/// @brief exception indicating a parse error
 | 
						|
/// @sa https://json.nlohmann.me/api/basic_json/parse_error/
 | 
						|
class parse_error : public exception
 | 
						|
{
 | 
						|
  public:
 | 
						|
    /*!
 | 
						|
    @brief create a parse error exception
 | 
						|
    @param[in] id_       the id of the exception
 | 
						|
    @param[in] pos       the position where the error occurred (or with
 | 
						|
                         chars_read_total=0 if the position cannot be
 | 
						|
                         determined)
 | 
						|
    @param[in] what_arg  the explanatory string
 | 
						|
    @return parse_error object
 | 
						|
    */
 | 
						|
    template<typename BasicJsonType>
 | 
						|
    static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
 | 
						|
    {
 | 
						|
        std::string w = exception::name("parse_error", id_) + "parse error" +
 | 
						|
                        position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
 | 
						|
        return {id_, pos.chars_read_total, w.c_str()};
 | 
						|
    }
 | 
						|
 | 
						|
    template<typename BasicJsonType>
 | 
						|
    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
 | 
						|
    {
 | 
						|
        std::string w = exception::name("parse_error", id_) + "parse error" +
 | 
						|
                        (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
 | 
						|
                        ": " + exception::diagnostics(context) + what_arg;
 | 
						|
        return {id_, byte_, w.c_str()};
 | 
						|
    }
 | 
						|
 | 
						|
    /*!
 | 
						|
    @brief byte index of the parse error
 | 
						|
 | 
						|
    The byte index of the last read character in the input file.
 | 
						|
 | 
						|
    @note For an input with n bytes, 1 is the index of the first character and
 | 
						|
          n+1 is the index of the terminating null byte or the end of file.
 | 
						|
          This also holds true when reading a byte vector (CBOR or MessagePack).
 | 
						|
    */
 | 
						|
    const std::size_t byte;
 | 
						|
 | 
						|
  private:
 | 
						|
    parse_error(int id_, std::size_t byte_, const char* what_arg)
 | 
						|
        : exception(id_, what_arg), byte(byte_) {}
 | 
						|
 | 
						|
    static std::string position_string(const position_t& pos)
 | 
						|
    {
 | 
						|
        return " at line " + std::to_string(pos.lines_read + 1) +
 | 
						|
               ", column " + std::to_string(pos.chars_read_current_line);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
/// @brief exception indicating errors with iterators
 | 
						|
/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/
 | 
						|
class invalid_iterator : public exception
 | 
						|
{
 | 
						|
  public:
 | 
						|
    template<typename BasicJsonType>
 | 
						|
    static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
 | 
						|
    {
 | 
						|
        std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
 | 
						|
        return {id_, w.c_str()};
 | 
						|
    }
 | 
						|
 | 
						|
  private:
 | 
						|
    JSON_HEDLEY_NON_NULL(3)
 | 
						|
    invalid_iterator(int id_, const char* what_arg)
 | 
						|
        : exception(id_, what_arg) {}
 | 
						|
};
 | 
						|
 | 
						|
/// @brief exception indicating executing a member function with a wrong type
 | 
						|
/// @sa https://json.nlohmann.me/api/basic_json/type_error/
 | 
						|
class type_error : public exception
 | 
						|
{
 | 
						|
  public:
 | 
						|
    template<typename BasicJsonType>
 | 
						|
    static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
 | 
						|
    {
 | 
						|
        std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
 | 
						|
        return {id_, w.c_str()};
 | 
						|
    }
 | 
						|
 | 
						|
  private:
 | 
						|
    JSON_HEDLEY_NON_NULL(3)
 | 
						|
    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
 | 
						|
};
 | 
						|
 | 
						|
/// @brief exception indicating access out of the defined range
 | 
						|
/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/
 | 
						|
class out_of_range : public exception
 | 
						|
{
 | 
						|
  public:
 | 
						|
    template<typename BasicJsonType>
 | 
						|
    static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
 | 
						|
    {
 | 
						|
        std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
 | 
						|
        return {id_, w.c_str()};
 | 
						|
    }
 | 
						|
 | 
						|
  private:
 | 
						|
    JSON_HEDLEY_NON_NULL(3)
 | 
						|
    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
 | 
						|
};
 | 
						|
 | 
						|
/// @brief exception indicating other library errors
 | 
						|
/// @sa https://json.nlohmann.me/api/basic_json/other_error/
 | 
						|
class other_error : public exception
 | 
						|
{
 | 
						|
  public:
 | 
						|
    template<typename BasicJsonType>
 | 
						|
    static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
 | 
						|
    {
 | 
						|
        std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
 | 
						|
        return {id_, w.c_str()};
 | 
						|
    }
 | 
						|
 | 
						|
  private:
 | 
						|
    JSON_HEDLEY_NON_NULL(3)
 | 
						|
    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace detail
 | 
						|
}  // namespace nlohmann
 |