Skip to content

Commit

Permalink
Merge pull request #329 from beached/v3
Browse files Browse the repository at this point in the history
Workaround: Worked around MSVC compiler crash for some tests
  • Loading branch information
beached authored Oct 29, 2022
2 parents f324fbf + e0a422c commit b2ffb13
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 68 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ ipch/
nbproject/*
node_modules/
obj/
out/
publish/
sql/
TestResult.xml
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
cmake_minimum_required( VERSION 3.14 )

project( "daw-json-link"
VERSION "3.1.1"
VERSION "3.2.0"
DESCRIPTION "Static JSON parsing in C++"
HOMEPAGE_URL "https://github.com/beached/daw_json_link"
LANGUAGES C CXX )
Expand Down
3 changes: 2 additions & 1 deletion include/daw/json/impl/daw_json_parse_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ namespace daw::json {
using NeedClassPositions = std::bool_constant<(
( JsonMembers::must_be_class_member or ... ) )>;

#if not defined( _MSC_VER ) or defined( __clang__ )
// MSVC in C++20 mode has a bug. This works around it
#if (not defined( _MSC_VER ) or __cpp_constexpr <= 201700L) or defined( __clang__ )
auto known_locations = DAW_AS_CONSTANT(
( make_locations_info<ParseState, JsonMembers...>( ) ) );
#else
Expand Down
22 changes: 13 additions & 9 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,13 @@ add_test( NAME cookbook_variant4_test COMMAND cookbook_variant4_test ./cookbook_
add_dependencies( ci_tests cookbook_variant4_test )
add_dependencies( full cookbook_variant4_test )

add_executable( cookbook_variant5_test src/cookbook_variant5_test.cpp )
if( DAW_JSON_FULL_TESTS )
add_executable( cookbook_variant5_test src/cookbook_variant5_test.cpp )
add_test( NAME cookbook_variant5_test COMMAND cookbook_variant5_test ./cookbook_variant5.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
else()
add_executable( cookbook_variant5_test EXCLUDE_FROM_ALL src/cookbook_variant5_test.cpp )
endif()
target_link_libraries( cookbook_variant5_test PRIVATE json_test )
add_test( NAME cookbook_variant5_test COMMAND cookbook_variant5_test ./cookbook_variant5.json WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test_data/" )
add_dependencies( ci_tests cookbook_variant5_test )
add_dependencies( full cookbook_variant5_test )

Expand Down Expand Up @@ -881,7 +885,7 @@ include( ./cmake/git_properties.cmake )
if( GIT_FOUND )
message( STATUS "Git revision: ${SOURCE_CONTROL_REVISION}" )
add_executable( json_benchmark src/json_benchmark.cpp )
target_compile_definitions( json_benchmark PRIVATE -DSOURCE_CONTROL_REVISION="${BUILD_VERSION}" )
target_compile_definitions( json_benchmark PRIVATE -DSOURCE_CONTROL_REVISION= "${BUILD_VERSION}" )
target_link_libraries( json_benchmark PRIVATE json_test )
if( DEFINED MSVC AND NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" )
add_compile_options( "/bigobj" )
Expand All @@ -897,12 +901,12 @@ if( GIT_FOUND )
string( REPLACE "#" "" _os_ver ${_os_ver} )
cmake_host_system_information( RESULT _os_plat QUERY OS_PLATFORM )
string( REPLACE "#" "" _os_plat ${_os_plat} )
target_compile_definitions( json_benchmark PRIVATE -DPROCESSOR_DESCRIPTION="${_proc_desc}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_NAME="${_os_name}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_RELEASE="${_os_rel}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_VERSION="${_os_ver}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_PLATFORM="${_os_plat}" )
target_compile_definitions( json_benchmark PRIVATE -DBUILD_TYPE="${CMAKE_BUILD_TYPE}" )
target_compile_definitions( json_benchmark PRIVATE -DPROCESSOR_DESCRIPTION= "${_proc_desc}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_NAME= "${_os_name}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_RELEASE= "${_os_rel}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_VERSION= "${_os_ver}" )
target_compile_definitions( json_benchmark PRIVATE -DOS_PLATFORM= "${_os_plat}" )
target_compile_definitions( json_benchmark PRIVATE -DBUILD_TYPE= "${CMAKE_BUILD_TYPE}" )
endif()
# **************************************************

27 changes: 15 additions & 12 deletions tests/src/out_of_order_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <cassert>
#include <iostream>
#include <optional>
#include <string_view>
#include <tuple>

Expand Down Expand Up @@ -61,16 +62,18 @@ namespace daw::json {
} // namespace daw::json

int main( ) {
std::string_view json_doc =
R"json({"b":"1.23456","a":"6.54321","d":"false","c":"true","f":"-123","e":"-321","h":"123","g":"321"})json";
auto const f = daw::json::from_json<Foo>( json_doc );
assert( f.a >= 6.54320 and f.a <= 6.54322 );
assert( f.b >= 1.23455 and f.b <= 1.23457 );
assert( f.c );
assert( not f.d );
assert( f.e == -321 );
assert( f.f == -123 );
assert( f.g == 321 );
assert( f.h == 123 );
std::cout << daw::json::to_json( f ) << '\n';
{
std::string_view json_doc =
R"json({"b":"1.23456","a":"6.54321","d":"false","c":"true","f":"-123","e":"-321","h":"123","g":"321"})json";
auto const f = daw::json::from_json<Foo>( json_doc );
assert( f.a >= 6.54320 and f.a <= 6.54322 );
assert( f.b >= 1.23455 and f.b <= 1.23457 );
assert( f.c );
assert( not f.d );
assert( f.e == -321 );
assert( f.f == -123 );
assert( f.g == 321 );
assert( f.h == 123 );
std::cout << daw::json::to_json( f ) << '\n';
}
}
92 changes: 47 additions & 45 deletions tests/src/test_details_parse_value_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ namespace daw::json {
};
} // namespace daw::json

bool empty_class_empty_json_class( ) {
using namespace daw::json;
using namespace daw::json::json_details;
using namespace daw::json;
using namespace daw::json::json_details;

bool empty_class_empty_json_class( ) {
std::string_view sv = "{}";
daw::do_not_optimize( sv );
auto rng = BasicParsePolicy( sv.data( ), sv.data( ) + sv.size( ) );
Expand All @@ -61,9 +61,6 @@ bool empty_class_empty_json_class( ) {
}

bool empty_class_nonempty_json_class( ) {
using namespace daw::json;
using namespace daw::json::json_details;

std::string_view sv = R"({ "a": 12345, "b": {} })";
daw::do_not_optimize( sv );
auto rng = BasicParsePolicy( sv.data( ), sv.data( ) + sv.size( ) );
Expand All @@ -73,82 +70,86 @@ bool empty_class_nonempty_json_class( ) {
return true;
}

// Fails on MSVC 2022 in C++17 mode.
#if not defined( _MSC_VER )
// putting member names/type alias into struct so that MSVC doesn't ICE
struct missing_members_fail_t {
static constexpr char const member0[] = "member0";
using class_t =
daw::json::tuple_json_mapping<daw::json::json_number<member0, unsigned>>;
};
bool missing_members_fail( ) {
using namespace daw::json;
using namespace daw::json::json_details;

std::string_view sv = "{}";
daw::do_not_optimize( sv );
auto rng = BasicParsePolicy( sv.data( ), sv.data( ) + sv.size( ) );
static constexpr char const member0[] = "member0";
using class_t = tuple_json_mapping<json_number<member0, unsigned>>;
auto v = parse_value<json_class_no_name<class_t>>(

auto v = parse_value<json_class_no_name<missing_members_fail_t::class_t>>(
rng, ParseTag<JsonParseTypes::Class>{ } );
daw::do_not_optimize( v );
return true;
}
#endif

struct wrong_member_type_fail_t {
static constexpr char const member0[] = "member0";
using class_t =
daw::json::tuple_json_mapping<daw::json::json_number<member0, unsigned>>;
};
bool wrong_member_type_fail( ) {
using namespace daw::json;
using namespace daw::json::json_details;

std::string_view sv = R"({ "member0": "this isn't a number" })";
daw::do_not_optimize( sv );
auto rng = BasicParsePolicy( sv.data( ), sv.data( ) + sv.size( ) );
static constexpr char const member0[] = "member0";
using class_t = tuple_json_mapping<json_number<member0, unsigned>>;
auto v = parse_value<json_class_no_name<class_t>>(

auto v = parse_value<json_class_no_name<wrong_member_type_fail_t::class_t>>(
rng, ParseTag<JsonParseTypes::Class>{ } );
daw::do_not_optimize( v );
return true;
}

struct wrong_member_number_type_fail_t {
static constexpr char const member0[] = "member0";
using class_t =
daw::json::tuple_json_mapping<daw::json::json_number<member0, unsigned>>;
};
bool wrong_member_number_type_fail( ) {
using namespace daw::json;
using namespace daw::json::json_details;

std::string_view sv = R"({ "member0": -123 })";
daw::do_not_optimize( sv );
auto rng = BasicParsePolicy( sv.data( ), sv.data( ) + sv.size( ) );
static constexpr char const member0[] = "member0";
using class_t = tuple_json_mapping<json_number<member0, unsigned>>;
auto v = parse_value<json_class_no_name<class_t>>(
rng, ParseTag<JsonParseTypes::Class>{ } );

auto v =
parse_value<json_class_no_name<wrong_member_number_type_fail_t::class_t>>(
rng, ParseTag<JsonParseTypes::Class>{ } );
daw::do_not_optimize( v );
return true;
}

struct unexpected_eof_in_class1_fail_t {
static constexpr char const member0[] = "member0";
using class_t = tuple_json_mapping<json_number<member0>>;
};
bool unexpected_eof_in_class1_fail( ) {
using namespace daw::json;
using namespace daw::json::json_details;

std::string_view sv = R"({ "member0": 123 )";
daw::do_not_optimize( sv );
auto rng = BasicParsePolicy( sv.data( ), sv.data( ) + sv.size( ) );
static constexpr char const member0[] = "member0";
using class_t = tuple_json_mapping<json_number<member0>>;
auto v = parse_value<json_class_no_name<class_t>>(

auto v = parse_value<json_class_no_name<unexpected_eof_in_class1_fail_t::class_t>>(
rng, ParseTag<JsonParseTypes::Class>{ } );
daw::do_not_optimize( v );
return true;
}

struct wrong_member_stored_pos_fail_t {
static constexpr char const member0[] = "member0";
static constexpr char const member1[] = "member1";
using class_t =
daw::json::tuple_json_mapping<daw::json::json_number<member0>,
daw::json::json_number<member1>>;
};
bool wrong_member_stored_pos_fail( ) {
using namespace daw::json;
using namespace daw::json::json_details;

std::string_view sv = R"({ "member1": 1, "member0": 2,)";
daw::do_not_optimize( sv );
auto rng = BasicParsePolicy( sv.data( ), sv.data( ) + sv.size( ) );
static constexpr char const member0[] = "member0";
static constexpr char const member1[] = "member1";
using class_t =
tuple_json_mapping<json_number<member0>, json_number<member1>>;
auto v = parse_value<json_class_no_name<class_t>>(
rng, ParseTag<JsonParseTypes::Class>{ } );

auto v =
parse_value<json_class_no_name<wrong_member_stored_pos_fail_t::class_t>>(
rng, ParseTag<JsonParseTypes::Class>{ } );
daw::do_not_optimize( v );
return true;
}
Expand All @@ -160,9 +161,10 @@ int main( int, char ** )
{
do_test( empty_class_empty_json_class( ) );
do_test( empty_class_nonempty_json_class( ) );
#if not defined( _MSC_VER )
do_fail_test( missing_members_fail( ) );
#if( not defined( _MSC_VER ) or __cpp_constexpr > 201700L ) or \
defined( __clang__ )
#endif
do_fail_test( missing_members_fail( ) );
do_fail_test( wrong_member_type_fail( ) );
do_fail_test( wrong_member_number_type_fail( ) );
do_fail_test( unexpected_eof_in_class1_fail( ) );
Expand Down

0 comments on commit b2ffb13

Please sign in to comment.