add Hedley annotations

parent 9a775bcb
...@@ -26,7 +26,7 @@ namespace detail ...@@ -26,7 +26,7 @@ namespace detail
template<typename BasicJsonType> template<typename BasicJsonType>
void from_json(const BasicJsonType& j, typename std::nullptr_t& n) void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
{ {
if (JSON_UNLIKELY(not j.is_null())) if (HEDLEY_UNLIKELY(not j.is_null()))
{ {
JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
} }
...@@ -66,7 +66,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) ...@@ -66,7 +66,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
template<typename BasicJsonType> template<typename BasicJsonType>
void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
{ {
if (JSON_UNLIKELY(not j.is_boolean())) if (HEDLEY_UNLIKELY(not j.is_boolean()))
{ {
JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
} }
...@@ -76,7 +76,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) ...@@ -76,7 +76,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
template<typename BasicJsonType> template<typename BasicJsonType>
void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
{ {
if (JSON_UNLIKELY(not j.is_string())) if (HEDLEY_UNLIKELY(not j.is_string()))
{ {
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
} }
...@@ -92,7 +92,7 @@ template < ...@@ -92,7 +92,7 @@ template <
int > = 0 > int > = 0 >
void from_json(const BasicJsonType& j, ConstructibleStringType& s) void from_json(const BasicJsonType& j, ConstructibleStringType& s)
{ {
if (JSON_UNLIKELY(not j.is_string())) if (HEDLEY_UNLIKELY(not j.is_string()))
{ {
JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
} }
...@@ -132,7 +132,7 @@ template<typename BasicJsonType, typename T, typename Allocator, ...@@ -132,7 +132,7 @@ template<typename BasicJsonType, typename T, typename Allocator,
enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0> enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l) void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
{ {
if (JSON_UNLIKELY(not j.is_array())) if (HEDLEY_UNLIKELY(not j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
} }
...@@ -149,7 +149,7 @@ template<typename BasicJsonType, typename T, ...@@ -149,7 +149,7 @@ template<typename BasicJsonType, typename T,
enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0> enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
void from_json(const BasicJsonType& j, std::valarray<T>& l) void from_json(const BasicJsonType& j, std::valarray<T>& l)
{ {
if (JSON_UNLIKELY(not j.is_array())) if (HEDLEY_UNLIKELY(not j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
} }
...@@ -236,7 +236,7 @@ auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) ...@@ -236,7 +236,7 @@ auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
j.template get<typename ConstructibleArrayType::value_type>(), j.template get<typename ConstructibleArrayType::value_type>(),
void()) void())
{ {
if (JSON_UNLIKELY(not j.is_array())) if (HEDLEY_UNLIKELY(not j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + JSON_THROW(type_error::create(302, "type must be array, but is " +
std::string(j.type_name()))); std::string(j.type_name())));
...@@ -249,7 +249,7 @@ template<typename BasicJsonType, typename ConstructibleObjectType, ...@@ -249,7 +249,7 @@ template<typename BasicJsonType, typename ConstructibleObjectType,
enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0> enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
{ {
if (JSON_UNLIKELY(not j.is_object())) if (HEDLEY_UNLIKELY(not j.is_object()))
{ {
JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
} }
...@@ -332,14 +332,14 @@ template <typename BasicJsonType, typename Key, typename Value, typename Compare ...@@ -332,14 +332,14 @@ template <typename BasicJsonType, typename Key, typename Value, typename Compare
typename BasicJsonType::string_t, Key>::value>> typename BasicJsonType::string_t, Key>::value>>
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m) void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
{ {
if (JSON_UNLIKELY(not j.is_array())) if (HEDLEY_UNLIKELY(not j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
} }
m.clear(); m.clear();
for (const auto& p : j) for (const auto& p : j)
{ {
if (JSON_UNLIKELY(not p.is_array())) if (HEDLEY_UNLIKELY(not p.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
} }
...@@ -352,14 +352,14 @@ template <typename BasicJsonType, typename Key, typename Value, typename Hash, t ...@@ -352,14 +352,14 @@ template <typename BasicJsonType, typename Key, typename Value, typename Hash, t
typename BasicJsonType::string_t, Key>::value>> typename BasicJsonType::string_t, Key>::value>>
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m) void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
{ {
if (JSON_UNLIKELY(not j.is_array())) if (HEDLEY_UNLIKELY(not j.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
} }
m.clear(); m.clear();
for (const auto& p : j) for (const auto& p : j)
{ {
if (JSON_UNLIKELY(not p.is_array())) if (HEDLEY_UNLIKELY(not p.is_array()))
{ {
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()))); JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
} }
...@@ -386,4 +386,4 @@ namespace ...@@ -386,4 +386,4 @@ namespace
{ {
constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
} // namespace } // namespace
} // namespace nlohmann } // namespace nlohmann
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <cstring> // memcpy, memmove #include <cstring> // memcpy, memmove
#include <limits> // numeric_limits #include <limits> // numeric_limits
#include <type_traits> // conditional #include <type_traits> // conditional
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann namespace nlohmann
{ {
...@@ -818,6 +819,7 @@ v = buf * 10^decimal_exponent ...@@ -818,6 +819,7 @@ v = buf * 10^decimal_exponent
len is the length of the buffer (number of decimal digits) len is the length of the buffer (number of decimal digits)
The buffer must be large enough, i.e. >= max_digits10. The buffer must be large enough, i.e. >= max_digits10.
*/ */
HEDLEY_NON_NULL(1)
inline void grisu2(char* buf, int& len, int& decimal_exponent, inline void grisu2(char* buf, int& len, int& decimal_exponent,
diyfp m_minus, diyfp v, diyfp m_plus) diyfp m_minus, diyfp v, diyfp m_plus)
{ {
...@@ -877,6 +879,7 @@ len is the length of the buffer (number of decimal digits) ...@@ -877,6 +879,7 @@ len is the length of the buffer (number of decimal digits)
The buffer must be large enough, i.e. >= max_digits10. The buffer must be large enough, i.e. >= max_digits10.
*/ */
template <typename FloatType> template <typename FloatType>
HEDLEY_NON_NULL(1)
void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
{ {
static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3, static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
...@@ -915,6 +918,8 @@ void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) ...@@ -915,6 +918,8 @@ void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
@return a pointer to the element following the exponent. @return a pointer to the element following the exponent.
@pre -1000 < e < 1000 @pre -1000 < e < 1000
*/ */
HEDLEY_NON_NULL(1)
HEDLEY_RETURNS_NON_NULL
inline char* append_exponent(char* buf, int e) inline char* append_exponent(char* buf, int e)
{ {
assert(e > -1000); assert(e > -1000);
...@@ -965,6 +970,8 @@ notation. Otherwise it will be printed in exponential notation. ...@@ -965,6 +970,8 @@ notation. Otherwise it will be printed in exponential notation.
@pre min_exp < 0 @pre min_exp < 0
@pre max_exp > 0 @pre max_exp > 0
*/ */
HEDLEY_NON_NULL(1)
HEDLEY_RETURNS_NON_NULL
inline char* format_buffer(char* buf, int len, int decimal_exponent, inline char* format_buffer(char* buf, int len, int decimal_exponent,
int min_exp, int max_exp) int min_exp, int max_exp)
{ {
...@@ -1048,6 +1055,8 @@ format. Returns an iterator pointing past-the-end of the decimal representation. ...@@ -1048,6 +1055,8 @@ format. Returns an iterator pointing past-the-end of the decimal representation.
@note The result is NOT null-terminated. @note The result is NOT null-terminated.
*/ */
template <typename FloatType> template <typename FloatType>
HEDLEY_NON_NULL(1, 2)
HEDLEY_RETURNS_NON_NULL
char* to_chars(char* first, const char* last, FloatType value) char* to_chars(char* first, const char* last, FloatType value)
{ {
static_cast<void>(last); // maybe unused - fix warning static_cast<void>(last); // maybe unused - fix warning
......
...@@ -341,4 +341,4 @@ namespace ...@@ -341,4 +341,4 @@ namespace
{ {
constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
} // namespace } // namespace
} // namespace nlohmann } // namespace nlohmann
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <string> // to_string #include <string> // to_string
#include <nlohmann/detail/input/position_t.hpp> #include <nlohmann/detail/input/position_t.hpp>
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann namespace nlohmann
{ {
...@@ -46,6 +47,7 @@ class exception : public std::exception ...@@ -46,6 +47,7 @@ class exception : public std::exception
{ {
public: public:
/// returns the explanatory string /// returns the explanatory string
HEDLEY_RETURNS_NON_NULL
const char* what() const noexcept override const char* what() const noexcept override
{ {
return m.what(); return m.what();
...@@ -55,6 +57,7 @@ class exception : public std::exception ...@@ -55,6 +57,7 @@ class exception : public std::exception
const int id; const int id;
protected: protected:
HEDLEY_NON_NULL(3)
exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
static std::string name(const std::string& ename, int id_) static std::string name(const std::string& ename, int id_)
...@@ -207,6 +210,7 @@ class invalid_iterator : public exception ...@@ -207,6 +210,7 @@ class invalid_iterator : public exception
} }
private: private:
HEDLEY_NON_NULL(3)
invalid_iterator(int id_, const char* what_arg) invalid_iterator(int id_, const char* what_arg)
: exception(id_, what_arg) {} : exception(id_, what_arg) {}
}; };
...@@ -260,6 +264,7 @@ class type_error : public exception ...@@ -260,6 +264,7 @@ class type_error : public exception
} }
private: private:
HEDLEY_NON_NULL(3)
type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
}; };
...@@ -306,6 +311,7 @@ class out_of_range : public exception ...@@ -306,6 +311,7 @@ class out_of_range : public exception
} }
private: private:
HEDLEY_NON_NULL(3)
out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
}; };
...@@ -343,6 +349,7 @@ class other_error : public exception ...@@ -343,6 +349,7 @@ class other_error : public exception
} }
private: private:
HEDLEY_NON_NULL(3)
other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
}; };
} // namespace detail } // namespace detail
......
...@@ -55,6 +55,7 @@ Input adapter for stdio file access. This adapter read only 1 byte and do not us ...@@ -55,6 +55,7 @@ Input adapter for stdio file access. This adapter read only 1 byte and do not us
class file_input_adapter : public input_adapter_protocol class file_input_adapter : public input_adapter_protocol
{ {
public: public:
HEDLEY_NON_NULL(2)
explicit file_input_adapter(std::FILE* f) noexcept explicit file_input_adapter(std::FILE* f) noexcept
: m_file(f) : m_file(f)
{} {}
...@@ -130,6 +131,7 @@ class input_stream_adapter : public input_adapter_protocol ...@@ -130,6 +131,7 @@ class input_stream_adapter : public input_adapter_protocol
class input_buffer_adapter : public input_adapter_protocol class input_buffer_adapter : public input_adapter_protocol
{ {
public: public:
HEDLEY_NON_NULL(2)
input_buffer_adapter(const char* b, const std::size_t l) noexcept input_buffer_adapter(const char* b, const std::size_t l) noexcept
: cursor(b), limit(b + l) : cursor(b), limit(b + l)
{} {}
...@@ -143,7 +145,7 @@ class input_buffer_adapter : public input_adapter_protocol ...@@ -143,7 +145,7 @@ class input_buffer_adapter : public input_adapter_protocol
std::char_traits<char>::int_type get_character() noexcept override std::char_traits<char>::int_type get_character() noexcept override
{ {
if (JSON_LIKELY(cursor < limit)) if (HEDLEY_LIKELY(cursor < limit))
{ {
return std::char_traits<char>::to_int_type(*(cursor++)); return std::char_traits<char>::to_int_type(*(cursor++));
} }
...@@ -333,6 +335,7 @@ class input_adapter ...@@ -333,6 +335,7 @@ class input_adapter
{ {
public: public:
// native support // native support
HEDLEY_NON_NULL(2)
input_adapter(std::FILE* file) input_adapter(std::FILE* file)
: ia(std::make_shared<file_input_adapter>(file)) {} : ia(std::make_shared<file_input_adapter>(file)) {}
/// input adapter for input stream /// input adapter for input stream
...@@ -401,7 +404,7 @@ class input_adapter ...@@ -401,7 +404,7 @@ class input_adapter
"each element in the iterator range must have the size of 1 byte"); "each element in the iterator range must have the size of 1 byte");
const auto len = static_cast<size_t>(std::distance(first, last)); const auto len = static_cast<size_t>(std::distance(first, last));
if (JSON_LIKELY(len > 0)) if (HEDLEY_LIKELY(len > 0))
{ {
// there is at least one element: use the address of first // there is at least one element: use the address of first
ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len); ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
......
...@@ -206,7 +206,7 @@ class json_sax_dom_parser ...@@ -206,7 +206,7 @@ class json_sax_dom_parser
{ {
ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) if (HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, JSON_THROW(out_of_range::create(408,
"excessive object size: " + std::to_string(len))); "excessive object size: " + std::to_string(len)));
...@@ -232,7 +232,7 @@ class json_sax_dom_parser ...@@ -232,7 +232,7 @@ class json_sax_dom_parser
{ {
ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) if (HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, JSON_THROW(out_of_range::create(408,
"excessive array size: " + std::to_string(len))); "excessive array size: " + std::to_string(len)));
...@@ -288,6 +288,7 @@ class json_sax_dom_parser ...@@ -288,6 +288,7 @@ class json_sax_dom_parser
object to which we can add elements object to which we can add elements
*/ */
template<typename Value> template<typename Value>
HEDLEY_RETURNS_NON_NULL
BasicJsonType* handle_value(Value&& v) BasicJsonType* handle_value(Value&& v)
{ {
if (ref_stack.empty()) if (ref_stack.empty())
...@@ -394,7 +395,7 @@ class json_sax_dom_callback_parser ...@@ -394,7 +395,7 @@ class json_sax_dom_callback_parser
ref_stack.push_back(val.second); ref_stack.push_back(val.second);
// check object limit // check object limit
if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) if (ref_stack.back() and HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len))); JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
} }
...@@ -457,7 +458,7 @@ class json_sax_dom_callback_parser ...@@ -457,7 +458,7 @@ class json_sax_dom_callback_parser
ref_stack.push_back(val.second); ref_stack.push_back(val.second);
// check array limit // check array limit
if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size())) if (ref_stack.back() and HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
{ {
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len))); JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
} }
......
...@@ -59,6 +59,7 @@ class lexer ...@@ -59,6 +59,7 @@ class lexer
}; };
/// return name of values of type token_type (only used for errors) /// return name of values of type token_type (only used for errors)
HEDLEY_RETURNS_NON_NULL
static const char* token_type_name(const token_type t) noexcept static const char* token_type_name(const token_type t) noexcept
{ {
switch (t) switch (t)
...@@ -200,7 +201,7 @@ class lexer ...@@ -200,7 +201,7 @@ class lexer
for (auto range = ranges.begin(); range != ranges.end(); ++range) for (auto range = ranges.begin(); range != ranges.end(); ++range)
{ {
get(); get();
if (JSON_LIKELY(*range <= current and current <= *(++range))) if (HEDLEY_LIKELY(*range <= current and current <= *(++range)))
{ {
add(current); add(current);
} }
...@@ -299,7 +300,7 @@ class lexer ...@@ -299,7 +300,7 @@ class lexer
const int codepoint1 = get_codepoint(); const int codepoint1 = get_codepoint();
int codepoint = codepoint1; // start with codepoint1 int codepoint = codepoint1; // start with codepoint1
if (JSON_UNLIKELY(codepoint1 == -1)) if (HEDLEY_UNLIKELY(codepoint1 == -1))
{ {
error_message = "invalid string: '\\u' must be followed by 4 hex digits"; error_message = "invalid string: '\\u' must be followed by 4 hex digits";
return token_type::parse_error; return token_type::parse_error;
...@@ -309,18 +310,18 @@ class lexer ...@@ -309,18 +310,18 @@ class lexer
if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF) if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
{ {
// expect next \uxxxx entry // expect next \uxxxx entry
if (JSON_LIKELY(get() == '\\' and get() == 'u')) if (HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
{ {
const int codepoint2 = get_codepoint(); const int codepoint2 = get_codepoint();
if (JSON_UNLIKELY(codepoint2 == -1)) if (HEDLEY_UNLIKELY(codepoint2 == -1))
{ {
error_message = "invalid string: '\\u' must be followed by 4 hex digits"; error_message = "invalid string: '\\u' must be followed by 4 hex digits";
return token_type::parse_error; return token_type::parse_error;
} }
// check if codepoint2 is a low surrogate // check if codepoint2 is a low surrogate
if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF)) if (HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
{ {
// overwrite codepoint // overwrite codepoint
codepoint = static_cast<int>( codepoint = static_cast<int>(
...@@ -347,7 +348,7 @@ class lexer ...@@ -347,7 +348,7 @@ class lexer
} }
else else
{ {
if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF)) if (HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
{ {
error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
return token_type::parse_error; return token_type::parse_error;
...@@ -722,7 +723,7 @@ class lexer ...@@ -722,7 +723,7 @@ class lexer
case 0xDE: case 0xDE:
case 0xDF: case 0xDF:
{ {
if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF}))) if (HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
{ {
return token_type::parse_error; return token_type::parse_error;
} }
...@@ -732,7 +733,7 @@ class lexer ...@@ -732,7 +733,7 @@ class lexer
// U+0800..U+0FFF: bytes E0 A0..BF 80..BF // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
case 0xE0: case 0xE0:
{ {
if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) if (HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
{ {
return token_type::parse_error; return token_type::parse_error;
} }
...@@ -756,7 +757,7 @@ class lexer ...@@ -756,7 +757,7 @@ class lexer
case 0xEE: case 0xEE:
case 0xEF: case 0xEF:
{ {
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
{ {
return token_type::parse_error; return token_type::parse_error;
} }
...@@ -766,7 +767,7 @@ class lexer ...@@ -766,7 +767,7 @@ class lexer
// U+D000..U+D7FF: bytes ED 80..9F 80..BF // U+D000..U+D7FF: bytes ED 80..9F 80..BF
case 0xED: case 0xED:
{ {
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
{ {
return token_type::parse_error; return token_type::parse_error;
} }
...@@ -776,7 +777,7 @@ class lexer ...@@ -776,7 +777,7 @@ class lexer
// U+10000..U+3FFFF F0 90..BF 80..BF 80..BF // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
case 0xF0: case 0xF0:
{ {
if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
{ {
return token_type::parse_error; return token_type::parse_error;
} }
...@@ -788,7 +789,7 @@ class lexer ...@@ -788,7 +789,7 @@ class lexer
case 0xF2: case 0xF2:
case 0xF3: case 0xF3:
{ {
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
{ {
return token_type::parse_error; return token_type::parse_error;
} }
...@@ -798,7 +799,7 @@ class lexer ...@@ -798,7 +799,7 @@ class lexer
// U+100000..U+10FFFF F4 80..8F 80..BF 80..BF // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
case 0xF4: case 0xF4:
{ {
if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) if (HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
{ {
return token_type::parse_error; return token_type::parse_error;
} }
...@@ -815,16 +816,19 @@ class lexer ...@@ -815,16 +816,19 @@ class lexer
} }
} }
HEDLEY_NON_NULL(2)
static void strtof(float& f, const char* str, char** endptr) noexcept static void strtof(float& f, const char* str, char** endptr) noexcept
{ {
f = std::strtof(str, endptr); f = std::strtof(str, endptr);
} }
HEDLEY_NON_NULL(2)
static void strtof(double& f, const char* str, char** endptr) noexcept static void strtof(double& f, const char* str, char** endptr) noexcept
{ {
f = std::strtod(str, endptr); f = std::strtod(str, endptr);
} }
HEDLEY_NON_NULL(2)
static void strtof(long double& f, const char* str, char** endptr) noexcept static void strtof(long double& f, const char* str, char** endptr) noexcept
{ {
f = std::strtold(str, endptr); f = std::strtold(str, endptr);
...@@ -1200,13 +1204,14 @@ scan_number_done: ...@@ -1200,13 +1204,14 @@ scan_number_done:
@param[in] length the length of the passed literal text @param[in] length the length of the passed literal text
@param[in] return_type the token type to return on success @param[in] return_type the token type to return on success
*/ */
HEDLEY_NON_NULL(2)
token_type scan_literal(const char* literal_text, const std::size_t length, token_type scan_literal(const char* literal_text, const std::size_t length,
token_type return_type) token_type return_type)
{ {
assert(current == literal_text[0]); assert(current == literal_text[0]);
for (std::size_t i = 1; i < length; ++i) for (std::size_t i = 1; i < length; ++i)
{ {
if (JSON_UNLIKELY(get() != literal_text[i])) if (HEDLEY_UNLIKELY(get() != literal_text[i]))
{ {
error_message = "invalid literal"; error_message = "invalid literal";
return token_type::parse_error; return token_type::parse_error;
...@@ -1252,7 +1257,7 @@ scan_number_done: ...@@ -1252,7 +1257,7 @@ scan_number_done:
current = ia->get_character(); current = ia->get_character();
} }
if (JSON_LIKELY(current != std::char_traits<char>::eof())) if (HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
{ {
token_string.push_back(std::char_traits<char>::to_char_type(current)); token_string.push_back(std::char_traits<char>::to_char_type(current));
} }
...@@ -1293,7 +1298,7 @@ scan_number_done: ...@@ -1293,7 +1298,7 @@ scan_number_done:
--position.chars_read_current_line; --position.chars_read_current_line;
} }
if (JSON_LIKELY(current != std::char_traits<char>::eof())) if (HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
{ {
assert(not token_string.empty()); assert(not token_string.empty());
token_string.pop_back(); token_string.pop_back();
...@@ -1372,6 +1377,7 @@ scan_number_done: ...@@ -1372,6 +1377,7 @@ scan_number_done:
} }
/// return syntax error message /// return syntax error message
HEDLEY_RETURNS_NON_NULL
constexpr const char* get_error_message() const noexcept constexpr const char* get_error_message() const noexcept
{ {
return error_message; return error_message;
......
...@@ -147,6 +147,7 @@ class parser ...@@ -147,6 +147,7 @@ class parser
} }
template <typename SAX> template <typename SAX>
HEDLEY_NON_NULL(2)
bool sax_parse(SAX* sax, const bool strict = true) bool sax_parse(SAX* sax, const bool strict = true)
{ {
(void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
...@@ -166,6 +167,7 @@ class parser ...@@ -166,6 +167,7 @@ class parser
private: private:
template <typename SAX> template <typename SAX>
HEDLEY_NON_NULL(2)
bool sax_parse_internal(SAX* sax) bool sax_parse_internal(SAX* sax)
{ {
// stack to remember the hierarchy of structured values we are parsing // stack to remember the hierarchy of structured values we are parsing
...@@ -183,7 +185,7 @@ class parser ...@@ -183,7 +185,7 @@ class parser
{ {
case token_type::begin_object: case token_type::begin_object:
{ {
if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1)))) if (HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
{ {
return false; return false;
} }
...@@ -191,7 +193,7 @@ class parser ...@@ -191,7 +193,7 @@ class parser
// closing } -> we are done // closing } -> we are done
if (get_token() == token_type::end_object) if (get_token() == token_type::end_object)
{ {
if (JSON_UNLIKELY(not sax->end_object())) if (HEDLEY_UNLIKELY(not sax->end_object()))
{ {
return false; return false;
} }
...@@ -199,20 +201,20 @@ class parser ...@@ -199,20 +201,20 @@ class parser
} }
// parse key // parse key
if (JSON_UNLIKELY(last_token != token_type::value_string)) if (HEDLEY_UNLIKELY(last_token != token_type::value_string))
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), parse_error::create(101, m_lexer.get_position(),
exception_message(token_type::value_string, "object key"))); exception_message(token_type::value_string, "object key")));
} }
if (JSON_UNLIKELY(not sax->key(m_lexer.get_string()))) if (HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
{ {
return false; return false;
} }
// parse separator (:) // parse separator (:)
if (JSON_UNLIKELY(get_token() != token_type::name_separator)) if (HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
...@@ -230,7 +232,7 @@ class parser ...@@ -230,7 +232,7 @@ class parser
case token_type::begin_array: case token_type::begin_array:
{ {
if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1)))) if (HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
{ {
return false; return false;
} }
...@@ -238,7 +240,7 @@ class parser ...@@ -238,7 +240,7 @@ class parser
// closing ] -> we are done // closing ] -> we are done
if (get_token() == token_type::end_array) if (get_token() == token_type::end_array)
{ {
if (JSON_UNLIKELY(not sax->end_array())) if (HEDLEY_UNLIKELY(not sax->end_array()))
{ {
return false; return false;
} }
...@@ -256,14 +258,14 @@ class parser ...@@ -256,14 +258,14 @@ class parser
{ {
const auto res = m_lexer.get_number_float(); const auto res = m_lexer.get_number_float();
if (JSON_UNLIKELY(not std::isfinite(res))) if (HEDLEY_UNLIKELY(not std::isfinite(res)))
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'")); out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
} }
if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string()))) if (HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
{ {
return false; return false;
} }
...@@ -273,7 +275,7 @@ class parser ...@@ -273,7 +275,7 @@ class parser
case token_type::literal_false: case token_type::literal_false:
{ {
if (JSON_UNLIKELY(not sax->boolean(false))) if (HEDLEY_UNLIKELY(not sax->boolean(false)))
{ {
return false; return false;
} }
...@@ -282,7 +284,7 @@ class parser ...@@ -282,7 +284,7 @@ class parser
case token_type::literal_null: case token_type::literal_null:
{ {
if (JSON_UNLIKELY(not sax->null())) if (HEDLEY_UNLIKELY(not sax->null()))
{ {
return false; return false;
} }
...@@ -291,7 +293,7 @@ class parser ...@@ -291,7 +293,7 @@ class parser
case token_type::literal_true: case token_type::literal_true:
{ {
if (JSON_UNLIKELY(not sax->boolean(true))) if (HEDLEY_UNLIKELY(not sax->boolean(true)))
{ {
return false; return false;
} }
...@@ -300,7 +302,7 @@ class parser ...@@ -300,7 +302,7 @@ class parser
case token_type::value_integer: case token_type::value_integer:
{ {
if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer()))) if (HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
{ {
return false; return false;
} }
...@@ -309,7 +311,7 @@ class parser ...@@ -309,7 +311,7 @@ class parser
case token_type::value_string: case token_type::value_string:
{ {
if (JSON_UNLIKELY(not sax->string(m_lexer.get_string()))) if (HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
{ {
return false; return false;
} }
...@@ -318,7 +320,7 @@ class parser ...@@ -318,7 +320,7 @@ class parser
case token_type::value_unsigned: case token_type::value_unsigned:
{ {
if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned()))) if (HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
{ {
return false; return false;
} }
...@@ -366,9 +368,9 @@ class parser ...@@ -366,9 +368,9 @@ class parser
} }
// closing ] // closing ]
if (JSON_LIKELY(last_token == token_type::end_array)) if (HEDLEY_LIKELY(last_token == token_type::end_array))
{ {
if (JSON_UNLIKELY(not sax->end_array())) if (HEDLEY_UNLIKELY(not sax->end_array()))
{ {
return false; return false;
} }
...@@ -394,7 +396,7 @@ class parser ...@@ -394,7 +396,7 @@ class parser
if (get_token() == token_type::value_separator) if (get_token() == token_type::value_separator)
{ {
// parse key // parse key
if (JSON_UNLIKELY(get_token() != token_type::value_string)) if (HEDLEY_UNLIKELY(get_token() != token_type::value_string))
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
...@@ -402,13 +404,13 @@ class parser ...@@ -402,13 +404,13 @@ class parser
exception_message(token_type::value_string, "object key"))); exception_message(token_type::value_string, "object key")));
} }
if (JSON_UNLIKELY(not sax->key(m_lexer.get_string()))) if (HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
{ {
return false; return false;
} }
// parse separator (:) // parse separator (:)
if (JSON_UNLIKELY(get_token() != token_type::name_separator)) if (HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
{ {
return sax->parse_error(m_lexer.get_position(), return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(), m_lexer.get_token_string(),
...@@ -422,9 +424,9 @@ class parser ...@@ -422,9 +424,9 @@ class parser
} }
// closing } // closing }
if (JSON_LIKELY(last_token == token_type::end_object)) if (HEDLEY_LIKELY(last_token == token_type::end_object))
{ {
if (JSON_UNLIKELY(not sax->end_object())) if (HEDLEY_UNLIKELY(not sax->end_object()))
{ {
return false; return false;
} }
......
...@@ -126,7 +126,8 @@ class iter_impl ...@@ -126,7 +126,8 @@ class iter_impl
information refer to: https://github.com/nlohmann/json/issues/1608 information refer to: https://github.com/nlohmann/json/issues/1608
*/ */
iter_impl(const iter_impl<const BasicJsonType>& other) noexcept iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
: m_object(other.m_object), m_it(other.m_it) {} : m_object(other.m_object), m_it(other.m_it)
{}
/*! /*!
@brief converting constructor @brief converting constructor
...@@ -134,7 +135,8 @@ class iter_impl ...@@ -134,7 +135,8 @@ class iter_impl
@note It is not checked whether @a other is initialized. @note It is not checked whether @a other is initialized.
*/ */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
: m_object(other.m_object), m_it(other.m_it) {} : m_object(other.m_object), m_it(other.m_it)
{}
/*! /*!
@brief converting assignment @brief converting assignment
...@@ -149,6 +151,14 @@ class iter_impl ...@@ -149,6 +151,14 @@ class iter_impl
return *this; return *this;
} }
/// @copydoc operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>&)
iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
{
m_object = other.m_object;
m_it = other.m_it;
return *this;
}
private: private:
/*! /*!
@brief set the iterator to the first value @brief set the iterator to the first value
...@@ -245,7 +255,7 @@ class iter_impl ...@@ -245,7 +255,7 @@ class iter_impl
default: default:
{ {
if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) if (HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
{ {
return *m_object; return *m_object;
} }
...@@ -279,7 +289,7 @@ class iter_impl ...@@ -279,7 +289,7 @@ class iter_impl
default: default:
{ {
if (JSON_LIKELY(m_it.primitive_iterator.is_begin())) if (HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
{ {
return m_object; return m_object;
} }
...@@ -382,7 +392,7 @@ class iter_impl ...@@ -382,7 +392,7 @@ class iter_impl
bool operator==(const iter_impl& other) const bool operator==(const iter_impl& other) const
{ {
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (JSON_UNLIKELY(m_object != other.m_object)) if (HEDLEY_UNLIKELY(m_object != other.m_object))
{ {
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
} }
...@@ -418,7 +428,7 @@ class iter_impl ...@@ -418,7 +428,7 @@ class iter_impl
bool operator<(const iter_impl& other) const bool operator<(const iter_impl& other) const
{ {
// if objects are not the same, the comparison is undefined // if objects are not the same, the comparison is undefined
if (JSON_UNLIKELY(m_object != other.m_object)) if (HEDLEY_UNLIKELY(m_object != other.m_object))
{ {
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers")); JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
} }
...@@ -578,7 +588,7 @@ class iter_impl ...@@ -578,7 +588,7 @@ class iter_impl
default: default:
{ {
if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n)) if (HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
{ {
return *m_object; return *m_object;
} }
...@@ -596,7 +606,7 @@ class iter_impl ...@@ -596,7 +606,7 @@ class iter_impl
{ {
assert(m_object != nullptr); assert(m_object != nullptr);
if (JSON_LIKELY(m_object->is_object())) if (HEDLEY_LIKELY(m_object->is_object()))
{ {
return m_it.object_iterator->first; return m_it.object_iterator->first;
} }
...@@ -619,5 +629,5 @@ class iter_impl ...@@ -619,5 +629,5 @@ class iter_impl
/// the actual iterator of the associated instance /// the actual iterator of the associated instance
internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {}; internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
}; };
} // namespace detail } // namespace detail
} // namespace nlohmann } // namespace nlohmann
...@@ -244,7 +244,7 @@ class json_pointer ...@@ -244,7 +244,7 @@ class json_pointer
*/ */
void pop_back() void pop_back()
{ {
if (JSON_UNLIKELY(empty())) if (HEDLEY_UNLIKELY(empty()))
{ {
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
} }
...@@ -268,7 +268,7 @@ class json_pointer ...@@ -268,7 +268,7 @@ class json_pointer
*/ */
const std::string& back() const std::string& back()
{ {
if (JSON_UNLIKELY(empty())) if (HEDLEY_UNLIKELY(empty()))
{ {
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
} }
...@@ -332,7 +332,7 @@ class json_pointer ...@@ -332,7 +332,7 @@ class json_pointer
const int res = std::stoi(s, &processed_chars); const int res = std::stoi(s, &processed_chars);
// check if the string was completely read // check if the string was completely read
if (JSON_UNLIKELY(processed_chars != s.size())) if (HEDLEY_UNLIKELY(processed_chars != s.size()))
{ {
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
} }
...@@ -342,7 +342,7 @@ class json_pointer ...@@ -342,7 +342,7 @@ class json_pointer
json_pointer top() const json_pointer top() const
{ {
if (JSON_UNLIKELY(empty())) if (HEDLEY_UNLIKELY(empty()))
{ {
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent")); JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
} }
...@@ -474,7 +474,7 @@ class json_pointer ...@@ -474,7 +474,7 @@ class json_pointer
case detail::value_t::array: case detail::value_t::array:
{ {
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) if (HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
{ {
JSON_THROW(detail::parse_error::create(106, 0, JSON_THROW(detail::parse_error::create(106, 0,
"array index '" + reference_token + "array index '" + reference_token +
...@@ -532,7 +532,7 @@ class json_pointer ...@@ -532,7 +532,7 @@ class json_pointer
case detail::value_t::array: case detail::value_t::array:
{ {
if (JSON_UNLIKELY(reference_token == "-")) if (HEDLEY_UNLIKELY(reference_token == "-"))
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, JSON_THROW(detail::out_of_range::create(402,
...@@ -541,7 +541,7 @@ class json_pointer ...@@ -541,7 +541,7 @@ class json_pointer
} }
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) if (HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
{ {
JSON_THROW(detail::parse_error::create(106, 0, JSON_THROW(detail::parse_error::create(106, 0,
"array index '" + reference_token + "array index '" + reference_token +
...@@ -597,7 +597,7 @@ class json_pointer ...@@ -597,7 +597,7 @@ class json_pointer
case detail::value_t::array: case detail::value_t::array:
{ {
if (JSON_UNLIKELY(reference_token == "-")) if (HEDLEY_UNLIKELY(reference_token == "-"))
{ {
// "-" cannot be used for const access // "-" cannot be used for const access
JSON_THROW(detail::out_of_range::create(402, JSON_THROW(detail::out_of_range::create(402,
...@@ -606,7 +606,7 @@ class json_pointer ...@@ -606,7 +606,7 @@ class json_pointer
} }
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) if (HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
{ {
JSON_THROW(detail::parse_error::create(106, 0, JSON_THROW(detail::parse_error::create(106, 0,
"array index '" + reference_token + "array index '" + reference_token +
...@@ -656,7 +656,7 @@ class json_pointer ...@@ -656,7 +656,7 @@ class json_pointer
case detail::value_t::array: case detail::value_t::array:
{ {
if (JSON_UNLIKELY(reference_token == "-")) if (HEDLEY_UNLIKELY(reference_token == "-"))
{ {
// "-" always fails the range check // "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, JSON_THROW(detail::out_of_range::create(402,
...@@ -665,7 +665,7 @@ class json_pointer ...@@ -665,7 +665,7 @@ class json_pointer
} }
// error condition (cf. RFC 6901, Sect. 4) // error condition (cf. RFC 6901, Sect. 4)
if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0')) if (HEDLEY_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
{ {
JSON_THROW(detail::parse_error::create(106, 0, JSON_THROW(detail::parse_error::create(106, 0,
"array index '" + reference_token + "array index '" + reference_token +
...@@ -712,7 +712,7 @@ class json_pointer ...@@ -712,7 +712,7 @@ class json_pointer
} }
// check if nonempty reference string begins with slash // check if nonempty reference string begins with slash
if (JSON_UNLIKELY(reference_string[0] != '/')) if (HEDLEY_UNLIKELY(reference_string[0] != '/'))
{ {
JSON_THROW(detail::parse_error::create(107, 1, JSON_THROW(detail::parse_error::create(107, 1,
"JSON pointer must be empty or begin with '/' - was: '" + "JSON pointer must be empty or begin with '/' - was: '" +
...@@ -747,9 +747,9 @@ class json_pointer ...@@ -747,9 +747,9 @@ class json_pointer
assert(reference_token[pos] == '~'); assert(reference_token[pos] == '~');
// ~ must be followed by 0 or 1 // ~ must be followed by 0 or 1
if (JSON_UNLIKELY(pos == reference_token.size() - 1 or if (HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
(reference_token[pos + 1] != '0' and (reference_token[pos + 1] != '0' and
reference_token[pos + 1] != '1'))) reference_token[pos + 1] != '1')))
{ {
JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'")); JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
} }
...@@ -874,7 +874,7 @@ class json_pointer ...@@ -874,7 +874,7 @@ class json_pointer
static BasicJsonType static BasicJsonType
unflatten(const BasicJsonType& value) unflatten(const BasicJsonType& value)
{ {
if (JSON_UNLIKELY(not value.is_object())) if (HEDLEY_UNLIKELY(not value.is_object()))
{ {
JSON_THROW(detail::type_error::create(314, "only objects can be unflattened")); JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
} }
...@@ -884,7 +884,7 @@ class json_pointer ...@@ -884,7 +884,7 @@ class json_pointer
// iterate the JSON object values // iterate the JSON object values
for (const auto& element : *value.m_value.object) for (const auto& element : *value.m_value.object)
{ {
if (JSON_UNLIKELY(not element.second.is_primitive())) if (HEDLEY_UNLIKELY(not element.second.is_primitive()))
{ {
JSON_THROW(detail::type_error::create(315, "values in object must be primitive")); JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
} }
......
#pragma once #pragma once
#include <utility> // pair #include <utility> // pair
#include <nlohmann/thirdparty/hedley/hedley.hpp>
// This file contains all internal macro definitions // This file contains all internal macro definitions
// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
...@@ -38,32 +39,6 @@ ...@@ -38,32 +39,6 @@
#pragma GCC diagnostic ignored "-Wdocumentation" #pragma GCC diagnostic ignored "-Wdocumentation"
#endif #endif
// allow for portable deprecation warnings
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#define JSON_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define JSON_DEPRECATED __declspec(deprecated)
#else
#define JSON_DEPRECATED
#endif
// allow for portable nodiscard warnings
#if defined(__has_cpp_attribute)
#if __has_cpp_attribute(nodiscard)
#if defined(__clang__) && !defined(JSON_HAS_CPP_17) // issue #1535
#define JSON_NODISCARD
#else
#define JSON_NODISCARD [[nodiscard]]
#endif
#elif __has_cpp_attribute(gnu::warn_unused_result)
#define JSON_NODISCARD [[gnu::warn_unused_result]]
#else
#define JSON_NODISCARD
#endif
#else
#define JSON_NODISCARD
#endif
// allow to disable exceptions // allow to disable exceptions
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
#define JSON_THROW(exception) throw exception #define JSON_THROW(exception) throw exception
...@@ -98,15 +73,6 @@ ...@@ -98,15 +73,6 @@
#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
#endif #endif
// manual branch prediction
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#define JSON_LIKELY(x) __builtin_expect(x, 1)
#define JSON_UNLIKELY(x) __builtin_expect(x, 0)
#else
#define JSON_LIKELY(x) x
#define JSON_UNLIKELY(x) x
#endif
/*! /*!
@brief macro to briefly define a mapping between an enum and JSON @brief macro to briefly define a mapping between an enum and JSON
@def NLOHMANN_JSON_SERIALIZE_ENUM @def NLOHMANN_JSON_SERIALIZE_ENUM
......
...@@ -13,10 +13,6 @@ ...@@ -13,10 +13,6 @@
#undef JSON_CATCH #undef JSON_CATCH
#undef JSON_THROW #undef JSON_THROW
#undef JSON_TRY #undef JSON_TRY
#undef JSON_LIKELY
#undef JSON_UNLIKELY
#undef JSON_DEPRECATED
#undef JSON_NODISCARD
#undef JSON_HAS_CPP_14 #undef JSON_HAS_CPP_14
#undef JSON_HAS_CPP_17 #undef JSON_HAS_CPP_17
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> // string #include <string> // string
#include <nlohmann/detail/input/binary_reader.hpp> #include <nlohmann/detail/input/binary_reader.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/output/output_adapters.hpp> #include <nlohmann/detail/output/output_adapters.hpp>
namespace nlohmann namespace nlohmann
...@@ -714,7 +715,7 @@ class binary_writer ...@@ -714,7 +715,7 @@ class binary_writer
static std::size_t calc_bson_entry_header_size(const string_t& name) static std::size_t calc_bson_entry_header_size(const string_t& name)
{ {
const auto it = name.find(static_cast<typename string_t::value_type>(0)); const auto it = name.find(static_cast<typename string_t::value_type>(0));
if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos)) if (HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{ {
JSON_THROW(out_of_range::create(409, JSON_THROW(out_of_range::create(409,
"BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")")); "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <ostream> // basic_ostream #include <ostream> // basic_ostream
#include <string> // basic_string #include <string> // basic_string
#include <vector> // vector #include <vector> // vector
#include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann namespace nlohmann
{ {
...@@ -39,6 +40,7 @@ class output_vector_adapter : public output_adapter_protocol<CharType> ...@@ -39,6 +40,7 @@ class output_vector_adapter : public output_adapter_protocol<CharType>
v.push_back(c); v.push_back(c);
} }
HEDLEY_NON_NULL(2)
void write_characters(const CharType* s, std::size_t length) override void write_characters(const CharType* s, std::size_t length) override
{ {
std::copy(s, s + length, std::back_inserter(v)); std::copy(s, s + length, std::back_inserter(v));
...@@ -62,6 +64,7 @@ class output_stream_adapter : public output_adapter_protocol<CharType> ...@@ -62,6 +64,7 @@ class output_stream_adapter : public output_adapter_protocol<CharType>
stream.put(c); stream.put(c);
} }
HEDLEY_NON_NULL(2)
void write_characters(const CharType* s, std::size_t length) override void write_characters(const CharType* s, std::size_t length) override
{ {
stream.write(s, static_cast<std::streamsize>(length)); stream.write(s, static_cast<std::streamsize>(length));
...@@ -85,6 +88,7 @@ class output_string_adapter : public output_adapter_protocol<CharType> ...@@ -85,6 +88,7 @@ class output_string_adapter : public output_adapter_protocol<CharType>
str.push_back(c); str.push_back(c);
} }
HEDLEY_NON_NULL(2)
void write_characters(const CharType* s, std::size_t length) override void write_characters(const CharType* s, std::size_t length) override
{ {
str.append(s, length); str.append(s, length);
......
...@@ -110,7 +110,7 @@ class serializer ...@@ -110,7 +110,7 @@ class serializer
// variable to hold indentation for recursive calls // variable to hold indentation for recursive calls
const auto new_indent = current_indent + indent_step; const auto new_indent = current_indent + indent_step;
if (JSON_UNLIKELY(indent_string.size() < new_indent)) if (HEDLEY_UNLIKELY(indent_string.size() < new_indent))
{ {
indent_string.resize(indent_string.size() * 2, ' '); indent_string.resize(indent_string.size() * 2, ' ');
} }
...@@ -183,7 +183,7 @@ class serializer ...@@ -183,7 +183,7 @@ class serializer
// variable to hold indentation for recursive calls // variable to hold indentation for recursive calls
const auto new_indent = current_indent + indent_step; const auto new_indent = current_indent + indent_step;
if (JSON_UNLIKELY(indent_string.size() < new_indent)) if (HEDLEY_UNLIKELY(indent_string.size() < new_indent))
{ {
indent_string.resize(indent_string.size() * 2, ' '); indent_string.resize(indent_string.size() * 2, ' ');
} }
...@@ -498,7 +498,7 @@ class serializer ...@@ -498,7 +498,7 @@ class serializer
} }
// we finished processing the string // we finished processing the string
if (JSON_LIKELY(state == UTF8_ACCEPT)) if (HEDLEY_LIKELY(state == UTF8_ACCEPT))
{ {
// write buffer // write buffer
if (bytes > 0) if (bytes > 0)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment