diff --git a/CMakeLists.txt b/CMakeLists.txt index 9887657f..1b0bca9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,7 @@ option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF) ## CONFIGURATION ## set(NLOHMANN_JSON_TARGET_NAME ${PROJECT_NAME}) -set(NLOHMANN_JSON_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}" - CACHE INTERNAL "") +set(NLOHMANN_JSON_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}" CACHE INTERNAL "") set(NLOHMANN_JSON_INCLUDE_INSTALL_DIR "include") set(NLOHMANN_JSON_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") set(NLOHMANN_JSON_CMAKE_CONFIG_TEMPLATE "cmake/config.cmake.in") @@ -47,7 +46,7 @@ endif() ## add_library(${NLOHMANN_JSON_TARGET_NAME} INTERFACE) add_library(${PROJECT_NAME}::${NLOHMANN_JSON_TARGET_NAME} ALIAS ${NLOHMANN_JSON_TARGET_NAME}) -if (${CMAKE_VERSION} VERSION_LESS "3.8.0") +if (${CMAKE_VERSION} VERSION_LESS "3.8.0") target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_range_for) else() target_compile_features(${NLOHMANN_JSON_TARGET_NAME} INTERFACE cxx_std_11) diff --git a/Makefile b/Makefile index 39f3493f..be2fca4a 100644 --- a/Makefile +++ b/Makefile @@ -1,44 +1,31 @@ -.PHONY: pretty clean ChangeLog.md +.PHONY: pretty clean ChangeLog.md release -SRCS = include/nlohmann/json.hpp \ - include/nlohmann/json_fwd.hpp \ - include/nlohmann/adl_serializer.hpp \ - include/nlohmann/detail/conversions/from_json.hpp \ - include/nlohmann/detail/conversions/to_chars.hpp \ - include/nlohmann/detail/conversions/to_json.hpp \ - include/nlohmann/detail/exceptions.hpp \ - include/nlohmann/detail/input/binary_reader.hpp \ - include/nlohmann/detail/input/input_adapters.hpp \ - include/nlohmann/detail/input/json_sax.hpp \ - include/nlohmann/detail/input/lexer.hpp \ - include/nlohmann/detail/input/parser.hpp \ - include/nlohmann/detail/input/position_t.hpp \ - include/nlohmann/detail/iterators/internal_iterator.hpp \ - include/nlohmann/detail/iterators/iter_impl.hpp \ - include/nlohmann/detail/iterators/iteration_proxy.hpp \ - include/nlohmann/detail/iterators/json_reverse_iterator.hpp \ - include/nlohmann/detail/iterators/primitive_iterator.hpp \ - include/nlohmann/detail/json_pointer.hpp \ - include/nlohmann/detail/json_ref.hpp \ - include/nlohmann/detail/macro_scope.hpp \ - include/nlohmann/detail/macro_unscope.hpp \ - include/nlohmann/detail/meta/cpp_future.hpp \ - include/nlohmann/detail/meta/detected.hpp \ - include/nlohmann/detail/meta/type_traits.hpp \ - include/nlohmann/detail/meta/void_t.hpp \ - include/nlohmann/detail/output/binary_writer.hpp \ - include/nlohmann/detail/output/output_adapters.hpp \ - include/nlohmann/detail/output/serializer.hpp \ - include/nlohmann/detail/value_t.hpp - -UNAME = $(shell uname) -CXX=clang++ - -AMALGAMATED_FILE=single_include/nlohmann/json.hpp +########################################################################## +# configuration +########################################################################## # directory to recent compiler binaries COMPILER_DIR=/Users/niels/Documents/projects/compilers/local/bin +# find GNU sed to use `-i` parameter +SED:=$(shell command -v gsed || which sed) + + +########################################################################## +# source files +########################################################################## + +# the list of sources in the include folder +SRCS=$(shell find include -type f | sort) + +# the single header (amalgamated from the source files) +AMALGAMATED_FILE=single_include/nlohmann/json.hpp + + +########################################################################## +# documentation of the Makefile's targets +########################################################################## + # main target all: @echo "amalgamate - amalgamate file single_include/nlohmann/json.hpp from the include/nlohmann sources" @@ -64,6 +51,7 @@ all: @echo "pretty - beautify code with Artistic Style" @echo "run_benchmarks - build and run benchmarks" + ########################################################################## # unit tests ########################################################################## @@ -76,25 +64,19 @@ json_unit: check: $(MAKE) check -C test +# run unit tests and skip expensive tests check-fast: $(MAKE) check -C test TEST_PATTERN="" -# clean up -clean: - rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM - rm -fr benchmarks/files/numbers/*.json - rm -fr build_coverage build_benchmarks - $(MAKE) clean -Cdoc - $(MAKE) clean -Ctest - ########################################################################## # coverage ########################################################################## coverage: + rm -fr build_coverage mkdir build_coverage - cd build_coverage ; CXX=g++-7 cmake .. -GNinja -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON + cd build_coverage ; CXX=$(COMPILER_DIR)/g++ cmake .. -GNinja -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON cd build_coverage ; ninja cd build_coverage ; ctest -E '.*_default' -j10 cd build_coverage ; ninja lcov_html @@ -115,36 +97,35 @@ doctest: ########################################################################## # calling Clang with all warnings, except: +# -Wno-c++2a-compat: u8 literals will behave differently in C++20... +# -Wno-deprecated-declarations: the library deprecated some functions # -Wno-documentation-unknown-command: code uses user-defined commands like @complexity # -Wno-exit-time-destructors: warning in json code triggered by NLOHMANN_JSON_SERIALIZE_ENUM -# -Wno-keyword-macro: unit-tests use "#define private public" -# -Wno-deprecated-declarations: the library deprecated some functions -# -Wno-weak-vtables: exception class is defined inline, but has virtual method -# -Wno-range-loop-analysis: items tests "for(const auto i...)" # -Wno-float-equal: not all comparisons in the tests can be replaced by Approx -# -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches -# -Wno-c++2a-compat: u8 literals will behave differently in C++20... +# -Wno-keyword-macro: unit-tests use "#define private public" # -Wno-padded: padding is nothing to warn about +# -Wno-range-loop-analysis: items tests "for(const auto i...)" +# -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches +# -Wno-weak-vtables: exception class is defined inline, but has virtual method pedantic_clang: $(MAKE) json_unit CXX=$(COMPILER_DIR)/clang++ CXXFLAGS=" \ -std=c++11 -Wno-c++98-compat -Wno-c++98-compat-pedantic \ -Werror \ -Weverything \ + -Wno-c++2a-compat \ + -Wno-deprecated-declarations \ -Wno-documentation-unknown-command \ -Wno-exit-time-destructors \ - -Wno-keyword-macro \ - -Wno-deprecated-declarations \ - -Wno-weak-vtables \ - -Wno-range-loop-analysis \ -Wno-float-equal \ + -Wno-keyword-macro \ + -Wno-padded \ + -Wno-range-loop-analysis \ -Wno-switch-enum -Wno-covered-switch-default \ - -Wno-c++2a-compat \ - -Wno-c++17-extensions \ - -Wno-padded" + -Wno-weak-vtables" # calling GCC with most warnings pedantic_gcc: - $(MAKE) json_unit CXX=$(COMPILER_DIR)/g++ CXXFLAGS=" \ + $(MAKE) json_unit CXX=$(COMPILER_DIR)/g++ CXXFLAGS="-D_Atomic=volatile \ -std=c++11 \ -Waddress \ -Waddress-of-packed-member \ @@ -372,9 +353,10 @@ pedantic_gcc: ########################################################################## run_benchmarks: + rm -fr build_benchmarks mkdir build_benchmarks - cd build_benchmarks ; cmake ../benchmarks - cd build_benchmarks ; make + cd build_benchmarks ; cmake ../benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release + cd build_benchmarks ; ninja cd build_benchmarks ; ./json_benchmarks ########################################################################## @@ -436,28 +418,39 @@ fuzzing-stop: -killall fuzzer -killall afl-fuzz + ########################################################################## -# static analyzer +# Static analysis ########################################################################## -# call cppcheck on the main header file +# call cppcheck +# Note: this target is called by Travis cppcheck: cppcheck --enable=warning --inline-suppr --inconclusive --force --std=c++11 $(SRCS) --error-exitcode=1 -# compile and check with Clang Static Analyzer +# call Clang Static Analyzer clang_analyze: rm -fr clang_analyze_build mkdir clang_analyze_build cd clang_analyze_build ; CCC_CXX=$(COMPILER_DIR)/clang++ CXX=$(COMPILER_DIR)/clang++ $(COMPILER_DIR)/scan-build cmake .. -GNinja - cd clang_analyze_build ; $(COMPILER_DIR)/scan-build -enable-checker alpha.core.BoolAssignment,alpha.core.CallAndMessageUnInitRefArg,alpha.core.CastSize,alpha.core.CastToStruct,alpha.core.Conversion,alpha.core.DynamicTypeChecker,alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.core.SizeofPtr,alpha.core.StackAddressAsyncEscape,alpha.core.TestAfterDivZero,alpha.deadcode.UnreachableCode,core.builtin.BuiltinFunctions,core.builtin.NoReturnFunctions,core.CallAndMessage,core.DivideZero,core.DynamicTypePropagation,core.NonnilStringConstants,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,core.VLASize,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.SelfAssignment,deadcode.DeadStores,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull --use-c++=$(COMPILER_DIR)/clang++ --view -analyze-headers -o clang_analyze_build/report.html ninja + cd clang_analyze_build ; \ + $(COMPILER_DIR)/scan-build \ + -enable-checker alpha.core.BoolAssignment,alpha.core.CallAndMessageUnInitRefArg,alpha.core.CastSize,alpha.core.CastToStruct,alpha.core.Conversion,alpha.core.DynamicTypeChecker,alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.core.SizeofPtr,alpha.core.StackAddressAsyncEscape,alpha.core.TestAfterDivZero,alpha.deadcode.UnreachableCode,core.builtin.BuiltinFunctions,core.builtin.NoReturnFunctions,core.CallAndMessage,core.DivideZero,core.DynamicTypePropagation,core.NonnilStringConstants,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,core.VLASize,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.SelfAssignment,deadcode.DeadStores,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull \ + --use-c++=$(COMPILER_DIR)/clang++ -analyze-headers -o report ninja + open clang_analyze_build/report/*/index.html -# call cpplint (some errors expected due to false positives) +# call cpplint +# Note: some errors expected due to false positives cpplint: - third_party/cpplint/cpplint.py --filter=-whitespace,-legal,-readability/alt_tokens,-runtime/references,-runtime/explicit --quiet --recursive include + third_party/cpplint/cpplint.py \ + --filter=-whitespace,-legal,-readability/alt_tokens,-runtime/references,-runtime/explicit \ + --quiet --recursive $(SRCS) +# call Clang-Tidy clang_tidy: $(COMPILER_DIR)/clang-tidy $(SRCS) -- -Iinclude -std=c++11 +# call PVS-Studio Analyzer pvs_studio: rm -fr pvs_studio_build mkdir pvs_studio_build @@ -466,45 +459,70 @@ pvs_studio: cd pvs_studio_build ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs open pvs_studio_build/pvs/index.html +# call Infer static analyzer infer: rm -fr infer_build mkdir infer_build cd infer_build ; infer compile -- cmake .. ; infer run -- make -j 4 +# call OCLint static analyzer oclint: oclint $(SRCS) -report-type html -enable-global-analysis -o oclint_report.html -max-priority-1=10000 -max-priority-2=10000 -max-priority-3=10000 -- -std=c++11 -Iinclude open oclint_report.html +# execute the test suite with Clang sanitizers (address and undefined behavior) +clang_sanitize: + rm -fr clang_sanitize_build + mkdir clang_sanitize_build + cd clang_sanitize_build ; CXX=$(COMPILER_DIR)/clang++ cmake .. -DJSON_Sanitizer=On -DJSON_MultipleHeaders=ON -GNinja + cd clang_sanitize_build ; ninja + cd clang_sanitize_build ; ctest -E '.*_default' -j10 + + ########################################################################## -# maintainer targets +# Code format and source amalgamation ########################################################################## -# pretty printer +# call the Artistic Style pretty printer on all source files pretty: - astyle --style=allman --indent=spaces=4 --indent-modifiers \ - --indent-switches --indent-preproc-block --indent-preproc-define \ - --indent-col1-comments --pad-oper --pad-header --align-pointer=type \ - --align-reference=type --add-brackets --convert-tabs --close-templates \ - --lineend=linux --preserve-date --suffix=none --formatted \ - $(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp \ - benchmarks/src/benchmarks.cpp doc/examples/*.cpp + astyle \ + --style=allman \ + --indent=spaces=4 \ + --indent-modifiers \ + --indent-switches \ + --indent-preproc-block \ + --indent-preproc-define \ + --indent-col1-comments \ + --pad-oper \ + --pad-header \ + --align-pointer=type \ + --align-reference=type \ + --add-brackets \ + --convert-tabs \ + --close-templates \ + --lineend=linux \ + --preserve-date \ + --suffix=none \ + --formatted \ + $(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp # create single header file amalgamate: $(AMALGAMATED_FILE) +# call the amalgamation tool and pretty print $(AMALGAMATED_FILE): $(SRCS) third_party/amalgamate/amalgamate.py -c third_party/amalgamate/config.json -s . --verbose=yes $(MAKE) pretty -# check if single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources +# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources +# Note: this target is called by Travis check-amalgamation: @mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ @$(MAKE) amalgamate @diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false) @mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) -# check if every header in nlohmann includes sufficient headers to be compiled -# individually +# check if every header in nlohmann includes sufficient headers to be compiled individually check-single-includes: @for x in $(SRCS); do \ echo "Checking self-sufficiency of $$x..." ; \ @@ -513,29 +531,79 @@ check-single-includes: rm -f single_include_test.cpp single_include_test; \ done + ########################################################################## -# changelog +# CMake ########################################################################## +# grep "^option" CMakeLists.txt test/CMakeLists.txt | sed 's/(/ /' | awk '{print $2}' | xargs + +# check if all flags of our CMake files work +check_cmake_flags_do: + $(CMAKE_BINARY) --version + for flag in '' JSON_BuildTests JSON_Install JSON_MultipleHeaders JSON_Sanitizer JSON_Valgrind JSON_NoExceptions JSON_Coverage; do \ + rm -fr cmake_build; \ + mkdir cmake_build; \ + echo "$(CMAKE_BINARY) .. -D$$flag=On" ; \ + cd cmake_build ; \ + CXX=g++-8 $(CMAKE_BINARY) .. -D$$flag=On -DCMAKE_CXX_COMPILE_FEATURES="cxx_std_11;cxx_range_for" -DCMAKE_CXX_FLAGS="-std=gnu++11" ; \ + test -f Makefile || exit 1 ; \ + cd .. ; \ + done; + +# call target `check_cmake_flags_do` twice: once for minimal required CMake version 3.1.0 and once for the installed version +check_cmake_flags: + wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Darwin64.tar.gz + tar xfz cmake-3.1.0-Darwin64.tar.gz + CMAKE_BINARY=$(abspath cmake-3.1.0-Darwin64/CMake.app/Contents/bin/cmake) $(MAKE) check_cmake_flags_do + CMAKE_BINARY=$(shell which cmake) $(MAKE) check_cmake_flags_do + + +########################################################################## +# ChangeLog +########################################################################## + +# Create a ChangeLog based on the git log using the GitHub Changelog Generator +# (). + +# variable to control the diffs between the last released version and the current repository state NEXT_VERSION ?= "unreleased" ChangeLog.md: github_changelog_generator -o ChangeLog.md --simple-list --release-url https://github.com/nlohmann/json/releases/tag/%s --future-release $(NEXT_VERSION) - gsed -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md - gsed -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md + $(SED) -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md + $(SED) -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md ########################################################################## -# release +# Release files ########################################################################## +# Create the files for a release and add signatures and hashes. We use `--no-extra` to make the resulting ZIP file +# reproducible, see . + release: + rm -fr release_files mkdir release_files - zip -9 -r include.zip include/* + zip -9 --recurse-paths --no-extra include.zip $(SRCS) gpg --armor --detach-sig include.zip mv include.zip include.zip.asc release_files - gpg --armor --detach-sig single_include/nlohmann/json.hpp - cp single_include/nlohmann/json.hpp release_files - mv single_include/nlohmann/json.hpp.asc release_files + gpg --armor --detach-sig $(AMALGAMATED_FILE) + cp $(AMALGAMATED_FILE) release_files + mv $(AMALGAMATED_FILE).asc release_files cd release_files ; shasum -a 256 json.hpp > hashes.txt cd release_files ; shasum -a 256 include.zip >> hashes.txt + + +########################################################################## +# Maintenance +########################################################################## + +# clean up +clean: + rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html + rm -fr benchmarks/files/numbers/*.json + rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64 + rm -fr build_coverage build_benchmarks fuzz-testing clang_analyze_build pvs_studio_build infer_build clang_sanitize_build cmake_build + $(MAKE) clean -Cdoc + $(MAKE) clean -Ctest diff --git a/include/nlohmann/detail/iterators/iterator_traits.hpp b/include/nlohmann/detail/iterators/iterator_traits.hpp index 9806be8c..4cced80c 100644 --- a/include/nlohmann/detail/iterators/iterator_traits.hpp +++ b/include/nlohmann/detail/iterators/iterator_traits.hpp @@ -13,15 +13,16 @@ template struct iterator_types {}; template -struct iterator_types< +struct iterator_types < It, void_t> { - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; + typename It::reference, typename It::iterator_category >> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; }; // This is required as some compilers implement std::iterator_traits in a way that @@ -32,18 +33,19 @@ struct iterator_traits }; template -struct iterator_traits::value>> - : iterator_types +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types { }; template -struct iterator_traits::value>> { - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; }; } // namespace detail } // namespace nlohmann diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index ef138100..e41180a9 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -18,6 +18,14 @@ #endif #endif +// C++ language standard detection +#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 +#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 +#endif + // disable float-equal warnings on GCC/clang #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic push @@ -42,7 +50,11 @@ // allow for portable nodiscard warnings #if defined(__has_cpp_attribute) #if __has_cpp_attribute(nodiscard) - #define JSON_NODISCARD [[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 @@ -95,14 +107,6 @@ #define JSON_UNLIKELY(x) x #endif -// C++ language standard detection -#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 -#endif - /*! @brief macro to briefly define a mapping between an enum and JSON @def NLOHMANN_JSON_SERIALIZE_ENUM diff --git a/include/nlohmann/detail/meta/is_sax.hpp b/include/nlohmann/detail/meta/is_sax.hpp index 4a4f5bbd..88295bec 100644 --- a/include/nlohmann/detail/meta/is_sax.hpp +++ b/include/nlohmann/detail/meta/is_sax.hpp @@ -24,119 +24,119 @@ using number_integer_function_t = template using number_unsigned_function_t = - decltype(std::declval().number_unsigned(std::declval())); + decltype(std::declval().number_unsigned(std::declval())); template -using number_float_function_t = decltype(std::declval().number_float( - std::declval(), std::declval())); +using number_float_function_t = decltype(std::declval().number_float( + std::declval(), std::declval())); template using string_function_t = - decltype(std::declval().string(std::declval())); + decltype(std::declval().string(std::declval())); template using start_object_function_t = - decltype(std::declval().start_object(std::declval())); + decltype(std::declval().start_object(std::declval())); template using key_function_t = - decltype(std::declval().key(std::declval())); + decltype(std::declval().key(std::declval())); template -using end_object_function_t = decltype(std::declval().end_object()); +using end_object_function_t = decltype(std::declval().end_object()); template using start_array_function_t = - decltype(std::declval().start_array(std::declval())); + decltype(std::declval().start_array(std::declval())); template -using end_array_function_t = decltype(std::declval().end_array()); +using end_array_function_t = decltype(std::declval().end_array()); template -using parse_error_function_t = decltype(std::declval().parse_error( - std::declval(), std::declval(), - std::declval())); +using parse_error_function_t = decltype(std::declval().parse_error( + std::declval(), std::declval(), + std::declval())); template struct is_sax { -private: - static_assert(is_basic_json::value, - "BasicJsonType must be of type basic_json<...>"); + private: + static_assert(is_basic_json::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; + 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::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value && - is_detected_exact::value; + public: + static constexpr bool value = + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value; }; template struct is_sax_static_asserts { -private: - static_assert(is_basic_json::value, - "BasicJsonType must be of type basic_json<...>"); + private: + static_assert(is_basic_json::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; + 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::value, - "Missing/invalid function: bool null()"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool boolean(bool)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool number_integer(number_integer_t)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool string(string_t&)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool start_object(std::size_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool key(string_t&)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool end_object()"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool start_array(std::size_t)"); - static_assert(is_detected_exact::value, - "Missing/invalid function: bool end_array()"); - static_assert( - is_detected_exact::value, - "Missing/invalid function: bool parse_error(std::size_t, const " - "std::string&, const exception&)"); + public: + static_assert(is_detected_exact::value, + "Missing/invalid function: bool null()"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool boolean(bool)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool boolean(bool)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool number_integer(number_integer_t)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool string(string_t&)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool start_object(std::size_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool key(string_t&)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool end_object()"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool start_array(std::size_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool end_array()"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool parse_error(std::size_t, const " + "std::string&, const exception&)"); }; } // namespace detail } // namespace nlohmann diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 5003a4fa..1f11538c 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -469,6 +469,14 @@ class other_error : public exception #endif #endif +// C++ language standard detection +#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 +#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 +#endif + // disable float-equal warnings on GCC/clang #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic push @@ -493,7 +501,11 @@ class other_error : public exception // allow for portable nodiscard warnings #if defined(__has_cpp_attribute) #if __has_cpp_attribute(nodiscard) - #define JSON_NODISCARD [[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 @@ -546,14 +558,6 @@ class other_error : public exception #define JSON_UNLIKELY(x) x #endif -// C++ language standard detection -#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 -#endif - /*! @brief macro to briefly define a mapping between an enum and JSON @def NLOHMANN_JSON_SERIALIZE_ENUM diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 53fd3ae6..f6c8829b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,7 +6,7 @@ option(JSON_Coverage "Build test suite with coverage information" OFF) if(JSON_Sanitizer) message(STATUS "Building test suite with Clang sanitizer") if(NOT MSVC) - set(CMAKE_CXX_FLAGS "-g -O2 -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "-g -O2 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer") endif() endif() @@ -64,7 +64,6 @@ set_target_properties(doctest_main PROPERTIES COMPILE_DEFINITIONS "$<$:_SCL_SECURE_NO_WARNINGS>" COMPILE_OPTIONS "$<$:/EHsc;$<$:/Od>>" ) - if (${CMAKE_VERSION} VERSION_LESS "3.8.0") target_compile_features(doctest_main PUBLIC cxx_range_for) else() diff --git a/third_party/cpplint/LICENSE b/third_party/cpplint/LICENSE old mode 100755 new mode 100644 diff --git a/third_party/cpplint/README.rst b/third_party/cpplint/README.rst old mode 100755 new mode 100644 diff --git a/third_party/cpplint/update.sh b/third_party/cpplint/update.sh new file mode 100755 index 00000000..03b6785b --- /dev/null +++ b/third_party/cpplint/update.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +wget -N https://raw.githubusercontent.com/cpplint/cpplint/master/cpplint.py +wget -N https://raw.githubusercontent.com/cpplint/cpplint/master/LICENSE +wget -N https://raw.githubusercontent.com/cpplint/cpplint/master/README.rst