Skip to content

Commit

Permalink
Add C++17 copies of the test binaries (#3101)
Browse files Browse the repository at this point in the history
* ⚗️ add C++17 copies of the test binaries
* ⚗️ use proper header for filesystem
* 🚨 fix warnings
* ⚗️ do not use too old compilers with C++17
* ✅ add test
* 🔨 add more constraints #3097
* ⚗️ use fix from #3101 (comment)
* ⚗️ use fix from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90050
* 👷 use published CI image
  • Loading branch information
nlohmann authored Dec 29, 2021
1 parent 825d323 commit 6d31159
Show file tree
Hide file tree
Showing 27 changed files with 442 additions and 138 deletions.
4 changes: 3 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ Checks: '*,
-llvmlibc-*,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
-modernize-concat-nested-namespaces,
-modernize-use-nodiscard,
-modernize-use-trailing-return-type,
-readability-function-size,
-readability-function-cognitive-complexity,
-readability-function-size,
-readability-identifier-length,
-readability-magic-numbers,
-readability-redundant-access-specifiers,
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
jobs:
ci_test_clang:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.0.0
container: ghcr.io/nlohmann/json-ci:v2.1.0
steps:
- uses: actions/checkout@v2
- name: cmake
Expand All @@ -21,7 +21,7 @@ jobs:

ci_test_gcc:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.0.0
container: ghcr.io/nlohmann/json-ci:v2.1.0
steps:
- uses: actions/checkout@v2
- name: cmake
Expand All @@ -31,7 +31,7 @@ jobs:

ci_static_analysis:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.0.0
container: ghcr.io/nlohmann/json-ci:v2.1.0
strategy:
matrix:
target: [ci_clang_tidy, ci_cppcheck, ci_test_valgrind, ci_test_clang_sanitizer, ci_test_amalgamation, ci_clang_analyze, ci_cpplint, ci_cmake_flags, ci_single_binaries, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_infer]
Expand All @@ -44,7 +44,7 @@ jobs:

ci_cmake_options:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.0.0
container: ghcr.io/nlohmann/json-ci:v2.1.0
strategy:
matrix:
target: [ci_test_diagnostics, ci_test_noexceptions, ci_test_noimplicitconversions]
Expand All @@ -57,7 +57,7 @@ jobs:

ci_test_coverage:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.0.0
container: ghcr.io/nlohmann/json-ci:v2.1.0
steps:
- uses: actions/checkout@v2
- name: cmake
Expand All @@ -77,7 +77,7 @@ jobs:

ci_test_compilers:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.0.0
container: ghcr.io/nlohmann/json-ci:v2.1.0
strategy:
matrix:
compiler: [g++-4.8, g++-4.9, g++-5, g++-6, g++-7, g++-8, g++-9, g++-10, clang++-3.5, clang++-3.6, clang++-3.7, clang++-3.8, clang++-3.9, clang++-4.0, clang++-5.0, clang++-6.0, clang++-7, clang++-8, clang++-9, clang++-10, clang++-11, clang++-12, clang++-13]
Expand All @@ -90,7 +90,7 @@ jobs:

ci_test_standards:
runs-on: ubuntu-latest
container: ghcr.io/nlohmann/json-ci:v2.0.0
container: ghcr.io/nlohmann/json-ci:v2.1.0
strategy:
matrix:
standard: [11, 14, 17, 20]
Expand Down
8 changes: 8 additions & 0 deletions cmake/ci.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -814,11 +814,19 @@ add_custom_target(ci_cmake_flags
foreach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6 g++-7 g++-8 g++-9 g++-10 clang++-3.5 clang++-3.6 clang++-3.7 clang++-3.8 clang++-3.9 clang++-4.0 clang++-5.0 clang++-6.0 clang++-7 clang++-8 clang++-9 clang++-10 clang++-11 clang++-12 clang++-13)
find_program(COMPILER_TOOL NAMES ${COMPILER})
if (COMPILER_TOOL)
if ("${COMPILER}" STREQUAL "clang++-9")
# fix for https://github.com/nlohmann/json/pull/3101#issuecomment-998788786 / https://stackoverflow.com/a/64051725/266378
set(ADDITIONAL_FLAGS "-DCMAKE_CXX_FLAGS=--gcc-toolchain=/root/gcc/9")
else()
unset(ADDITIONAL_FLAGS)
endif()

add_custom_target(ci_test_compiler_${COMPILER}
COMMAND CXX=${COMPILER} ${CMAKE_COMMAND}
-DCMAKE_BUILD_TYPE=Debug -GNinja
-DJSON_BuildTests=ON -DJSON_FastTests=ON
-S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
${ADDITIONAL_FLAGS}
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER}
COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure
COMMENT "Compile and test with ${COMPILER}"
Expand Down
7 changes: 7 additions & 0 deletions doc/mkdocs/docs/features/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ The diagnostics messages can also be controlled with the CMake option `JSON_Diag

The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.

## `JSON_HAS_FILESYSTEM`, `JSON_HAS_EXPERIMENTAL_FILESYSTEM`

When compiling with C++17, the library provides conversions from and to `std::filesystem::path`. As compiler support
for filesystem is limited, the library tries to detect whether `<filesystem>`/`std::filesystem` (`JSON_HAS_FILESYSTEM`)
or `<experimental/filesystem>`/`std::experimental::filesystem` (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used.
To override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`.

## `JSON_NOEXCEPTION`

Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`.
Expand Down
2 changes: 1 addition & 1 deletion include/nlohmann/byte_container_with_subtype.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class byte_container_with_subtype : public BinaryType
*/
constexpr subtype_type subtype() const noexcept
{
return m_has_subtype ? m_subtype : subtype_type(-1);
return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
}

/*!
Expand Down
18 changes: 14 additions & 4 deletions include/nlohmann/detail/conversions/from_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,18 @@
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp>

#ifdef JSON_HAS_CPP_17
#include <filesystem>
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::experimental::filesystem;
} // namespace nlohmann::detail
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::filesystem;
} // namespace nlohmann::detail
#endif

namespace nlohmann
Expand Down Expand Up @@ -448,9 +458,9 @@ void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyE
}
}

#ifdef JSON_HAS_CPP_17
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
template<typename BasicJsonType>
void from_json(const BasicJsonType& j, std::filesystem::path& p)
void from_json(const BasicJsonType& j, std_fs::path& p)
{
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
{
Expand Down
18 changes: 14 additions & 4 deletions include/nlohmann/detail/conversions/to_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,18 @@
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp>

#ifdef JSON_HAS_CPP_17
#include <filesystem>
#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
#include <experimental/filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::experimental::filesystem;
} // namespace nlohmann::detail
#elif JSON_HAS_FILESYSTEM
#include <filesystem>
namespace nlohmann::detail
{
namespace std_fs = std::filesystem;
} // namespace nlohmann::detail
#endif

namespace nlohmann
Expand Down Expand Up @@ -391,9 +401,9 @@ void to_json(BasicJsonType& j, const T& t)
to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
}

#ifdef JSON_HAS_CPP_17
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
template<typename BasicJsonType>
void to_json(BasicJsonType& j, const std::filesystem::path& p)
void to_json(BasicJsonType& j, const std_fs::path& p)
{
j = p.string();
}
Expand Down
24 changes: 12 additions & 12 deletions include/nlohmann/detail/input/binary_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class binary_reader
std::int32_t document_size{};
get_number<std::int32_t, true>(input_format_t::bson, document_size);

if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
{
return false;
}
Expand Down Expand Up @@ -318,7 +318,7 @@ class binary_reader
default: // anything else not supported (yet)
{
std::array<char, 3> cr{{}};
(std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
}
}
Expand Down Expand Up @@ -379,7 +379,7 @@ class binary_reader
std::int32_t document_size{};
get_number<std::int32_t, true>(input_format_t::bson, document_size);

if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
{
return false;
}
Expand Down Expand Up @@ -638,7 +638,7 @@ class binary_reader
}

case 0x9F: // array (indefinite length)
return get_cbor_array(std::size_t(-1), tag_handler);
return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);

// map (0x00..0x17 pairs of data items follow)
case 0xA0:
Expand Down Expand Up @@ -692,7 +692,7 @@ class binary_reader
}

case 0xBF: // map (indefinite length)
return get_cbor_object(std::size_t(-1), tag_handler);
return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);

case 0xC6: // tagged item
case 0xC7:
Expand Down Expand Up @@ -1076,7 +1076,7 @@ class binary_reader
}

/*!
@param[in] len the length of the array or std::size_t(-1) for an
@param[in] len the length of the array or static_cast<std::size_t>(-1) for an
array of indefinite size
@param[in] tag_handler how CBOR tags should be treated
@return whether array creation completed
Expand All @@ -1089,7 +1089,7 @@ class binary_reader
return false;
}

if (len != std::size_t(-1))
if (len != static_cast<std::size_t>(-1))
{
for (std::size_t i = 0; i < len; ++i)
{
Expand All @@ -1114,7 +1114,7 @@ class binary_reader
}

/*!
@param[in] len the length of the object or std::size_t(-1) for an
@param[in] len the length of the object or static_cast<std::size_t>(-1) for an
object of indefinite size
@param[in] tag_handler how CBOR tags should be treated
@return whether object creation completed
Expand All @@ -1130,7 +1130,7 @@ class binary_reader
if (len != 0)
{
string_t key;
if (len != std::size_t(-1))
if (len != static_cast<std::size_t>(-1))
{
for (std::size_t i = 0; i < len; ++i)
{
Expand Down Expand Up @@ -2140,7 +2140,7 @@ class binary_reader
}
else
{
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
{
return false;
}
Expand Down Expand Up @@ -2210,7 +2210,7 @@ class binary_reader
}
else
{
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
{
return false;
}
Expand Down Expand Up @@ -2462,7 +2462,7 @@ class binary_reader
std::string get_token_string() const
{
std::array<char, 3> cr{{}};
(std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
return std::string{cr.data()};
}

Expand Down
12 changes: 6 additions & 6 deletions include/nlohmann/detail/input/json_sax.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ class json_sax_dom_parser
{
ref_stack.push_back(handle_value(BasicJsonType::value_t::object));

if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
}
Expand All @@ -248,7 +248,7 @@ class json_sax_dom_parser
{
ref_stack.push_back(handle_value(BasicJsonType::value_t::array));

if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
}
Expand Down Expand Up @@ -403,7 +403,7 @@ class json_sax_dom_callback_parser
ref_stack.push_back(val.second);

// check object limit
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
}
Expand Down Expand Up @@ -473,7 +473,7 @@ class json_sax_dom_callback_parser
ref_stack.push_back(val.second);

// check array limit
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
{
JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
}
Expand Down Expand Up @@ -676,7 +676,7 @@ class json_sax_acceptor
return true;
}

bool start_object(std::size_t /*unused*/ = std::size_t(-1))
bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
{
return true;
}
Expand All @@ -691,7 +691,7 @@ class json_sax_acceptor
return true;
}

bool start_array(std::size_t /*unused*/ = std::size_t(-1))
bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
{
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions include/nlohmann/detail/input/lexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,7 @@ class lexer : public lexer_base<BasicJsonType>
{
// escape control characters
std::array<char, 9> cs{{}};
(std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
result += cs.data();
}
else
Expand Down Expand Up @@ -1541,17 +1541,17 @@ class lexer : public lexer_base<BasicJsonType>
// literals
case 't':
{
std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
}
case 'f':
{
std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
}
case 'n':
{
std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
}

Expand Down
4 changes: 2 additions & 2 deletions include/nlohmann/detail/input/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class parser
{
case token_type::begin_object:
{
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
{
return false;
}
Expand Down Expand Up @@ -231,7 +231,7 @@ class parser

case token_type::begin_array:
{
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
{
return false;
}
Expand Down
Loading

0 comments on commit 6d31159

Please sign in to comment.