add static_asserts on SAX interface
This commit is contained in:
		
							parent
							
								
									38f8a51a8f
								
							
						
					
					
						commit
						0cc3db4f15
					
				
					 4 changed files with 361 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -17,6 +17,7 @@
 | 
			
		|||
#include <nlohmann/detail/input/json_sax.hpp>
 | 
			
		||||
#include <nlohmann/detail/exceptions.hpp>
 | 
			
		||||
#include <nlohmann/detail/macro_scope.hpp>
 | 
			
		||||
#include <nlohmann/detail/meta/is_sax.hpp>
 | 
			
		||||
#include <nlohmann/detail/value_t.hpp>
 | 
			
		||||
 | 
			
		||||
namespace nlohmann
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +48,7 @@ class binary_reader
 | 
			
		|||
    */
 | 
			
		||||
    explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
 | 
			
		||||
    {
 | 
			
		||||
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
 | 
			
		||||
        assert(ia);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@
 | 
			
		|||
 | 
			
		||||
#include <nlohmann/detail/exceptions.hpp>
 | 
			
		||||
#include <nlohmann/detail/macro_scope.hpp>
 | 
			
		||||
#include <nlohmann/detail/meta/is_sax.hpp>
 | 
			
		||||
#include <nlohmann/detail/input/input_adapters.hpp>
 | 
			
		||||
#include <nlohmann/detail/input/json_sax.hpp>
 | 
			
		||||
#include <nlohmann/detail/input/lexer.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +146,7 @@ class parser
 | 
			
		|||
    template <typename SAX>
 | 
			
		||||
    bool sax_parse(SAX* sax, const bool strict = true)
 | 
			
		||||
    {
 | 
			
		||||
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType>{};
 | 
			
		||||
        const bool result = sax_parse_internal(sax);
 | 
			
		||||
 | 
			
		||||
        // strict mode: next byte must be EOF
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										141
									
								
								include/nlohmann/detail/meta/is_sax.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								include/nlohmann/detail/meta/is_sax.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,141 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <cstdint> // size_t
 | 
			
		||||
#include <utility> // declval
 | 
			
		||||
 | 
			
		||||
#include <nlohmann/detail/meta/detected.hpp>
 | 
			
		||||
#include <nlohmann/detail/meta/type_traits.hpp>
 | 
			
		||||
 | 
			
		||||
namespace nlohmann
 | 
			
		||||
{
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
template <typename T>
 | 
			
		||||
using null_function_t = decltype(std::declval<T&>().null());
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using boolean_function_t =
 | 
			
		||||
    decltype(std::declval<T&>().boolean(std::declval<bool>()));
 | 
			
		||||
 | 
			
		||||
template <typename T, typename Integer>
 | 
			
		||||
using number_integer_function_t =
 | 
			
		||||
    decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
 | 
			
		||||
 | 
			
		||||
template <typename T, typename Unsigned>
 | 
			
		||||
using number_unsigned_function_t =
 | 
			
		||||
    decltype(std::declval<T &>().number_unsigned(std::declval<Unsigned>()));
 | 
			
		||||
 | 
			
		||||
template <typename T, typename Float, typename String>
 | 
			
		||||
using number_float_function_t = decltype(std::declval<T &>().number_float(
 | 
			
		||||
    std::declval<Float>(), std::declval<const String &>()));
 | 
			
		||||
 | 
			
		||||
template <typename T, typename String>
 | 
			
		||||
using string_function_t =
 | 
			
		||||
    decltype(std::declval<T &>().string(std::declval<String &>()));
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using start_object_function_t =
 | 
			
		||||
    decltype(std::declval<T &>().start_object(std::declval<std::size_t>()));
 | 
			
		||||
 | 
			
		||||
template <typename T, typename String>
 | 
			
		||||
using key_function_t =
 | 
			
		||||
    decltype(std::declval<T &>().key(std::declval<String &>()));
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using end_object_function_t = decltype(std::declval<T &>().end_object());
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using start_array_function_t =
 | 
			
		||||
    decltype(std::declval<T &>().start_array(std::declval<std::size_t>()));
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using end_array_function_t = decltype(std::declval<T &>().end_array());
 | 
			
		||||
 | 
			
		||||
template <typename T, typename Exception>
 | 
			
		||||
using parse_error_function_t = decltype(std::declval<T &>().parse_error(
 | 
			
		||||
    std::declval<std::size_t>(), std::declval<const std::string &>(),
 | 
			
		||||
    std::declval<const Exception &>()));
 | 
			
		||||
 | 
			
		||||
template <typename SAX, typename BasicJsonType>
 | 
			
		||||
struct is_sax
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
  static_assert(is_basic_json<BasicJsonType>::value,
 | 
			
		||||
                "BasicJsonType must be of type basic_json<...>");
 | 
			
		||||
 | 
			
		||||
  using number_integer_t = typename BasicJsonType::number_integer_t;
 | 
			
		||||
  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
 | 
			
		||||
  using number_float_t = typename BasicJsonType::number_float_t;
 | 
			
		||||
  using string_t = typename BasicJsonType::string_t;
 | 
			
		||||
  using exception_t = typename BasicJsonType::exception;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  static constexpr bool value =
 | 
			
		||||
      is_detected_exact<bool, null_function_t, SAX>::value &&
 | 
			
		||||
      is_detected_exact<bool, boolean_function_t, SAX>::value &&
 | 
			
		||||
      is_detected_exact<bool, number_integer_function_t, SAX,
 | 
			
		||||
                        number_integer_t>::value &&
 | 
			
		||||
      is_detected_exact<bool, number_unsigned_function_t, SAX,
 | 
			
		||||
                        number_unsigned_t>::value &&
 | 
			
		||||
      is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
 | 
			
		||||
                        string_t>::value &&
 | 
			
		||||
      is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
 | 
			
		||||
      is_detected_exact<bool, start_object_function_t, SAX>::value &&
 | 
			
		||||
      is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
 | 
			
		||||
      is_detected_exact<bool, end_object_function_t, SAX>::value &&
 | 
			
		||||
      is_detected_exact<bool, start_array_function_t, SAX>::value &&
 | 
			
		||||
      is_detected_exact<bool, end_array_function_t, SAX>::value &&
 | 
			
		||||
      is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename SAX, typename BasicJsonType>
 | 
			
		||||
struct is_sax_static_asserts
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
  static_assert(is_basic_json<BasicJsonType>::value,
 | 
			
		||||
                "BasicJsonType must be of type basic_json<...>");
 | 
			
		||||
 | 
			
		||||
  using number_integer_t = typename BasicJsonType::number_integer_t;
 | 
			
		||||
  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
 | 
			
		||||
  using number_float_t = typename BasicJsonType::number_float_t;
 | 
			
		||||
  using string_t = typename BasicJsonType::string_t;
 | 
			
		||||
  using exception_t = typename BasicJsonType::exception;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
 | 
			
		||||
                "Missing/invalid function: bool null()");
 | 
			
		||||
  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
 | 
			
		||||
                "Missing/invalid function: bool boolean(bool)");
 | 
			
		||||
  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
 | 
			
		||||
                "Missing/invalid function: bool boolean(bool)");
 | 
			
		||||
  static_assert(
 | 
			
		||||
      is_detected_exact<bool, number_integer_function_t, SAX,
 | 
			
		||||
                        number_integer_t>::value,
 | 
			
		||||
      "Missing/invalid function: bool number_integer(number_integer_t)");
 | 
			
		||||
  static_assert(
 | 
			
		||||
      is_detected_exact<bool, number_unsigned_function_t, SAX,
 | 
			
		||||
                        number_unsigned_t>::value,
 | 
			
		||||
      "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
 | 
			
		||||
  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
 | 
			
		||||
                                  number_float_t, string_t>::value,
 | 
			
		||||
                "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
 | 
			
		||||
  static_assert(
 | 
			
		||||
      is_detected_exact<bool, string_function_t, SAX, string_t>::value,
 | 
			
		||||
      "Missing/invalid function: bool string(string_t&)");
 | 
			
		||||
  static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
 | 
			
		||||
                "Missing/invalid function: bool start_object(std::size_t)");
 | 
			
		||||
  static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
 | 
			
		||||
                "Missing/invalid function: bool key(string_t&)");
 | 
			
		||||
  static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
 | 
			
		||||
                "Missing/invalid function: bool end_object()");
 | 
			
		||||
  static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
 | 
			
		||||
                "Missing/invalid function: bool start_array(std::size_t)");
 | 
			
		||||
  static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
 | 
			
		||||
                "Missing/invalid function: bool end_array()");
 | 
			
		||||
  static_assert(
 | 
			
		||||
      is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
 | 
			
		||||
      "Missing/invalid function: bool parse_error(std::size_t, const "
 | 
			
		||||
      "std::string&, const exception&)");
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue