From 49baa03a175fec75ff9e1257647e5df4b95b14bd Mon Sep 17 00:00:00 2001 From: Shane Grant Date: Sun, 5 Nov 2017 19:07:31 -0800 Subject: [PATCH] Working towards cpp17 tests Progress towards #448 Lots of warnings from g++7.2, these are addressed in #423 which hasn't been merged yet. CMAKE can be cleaned up a bit - may put back in the ability to use older cmake and just throw errors as necessary, otherwise just force people to use at least cmake 3.1 --- CMakeLists.txt | 20 ++-- include/cereal/macros.hpp | 11 +++ include/cereal/types/optional.hpp | 6 +- include/cereal/types/variant.hpp | 2 +- unittests/CMakeLists.txt | 4 + unittests/cpp17/CMakeLists.txt | 38 ++++++++ .../types => unittests/cpp17}/optional.cpp | 58 +---------- unittests/cpp17/optional.hpp | 92 ++++++++++++++++++ unittests/cpp17/variant.cpp | 97 +++++++++++++++++++ unittests/{variant.cpp => cpp17/variant.hpp} | 0 10 files changed, 261 insertions(+), 67 deletions(-) create mode 100644 unittests/cpp17/CMakeLists.txt rename {include/cereal/types => unittests/cpp17}/optional.cpp (63%) create mode 100644 unittests/cpp17/optional.hpp create mode 100644 unittests/cpp17/variant.cpp rename unittests/{variant.cpp => cpp17/variant.hpp} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcb9cd677..a2ef4a201 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6.2) +cmake_minimum_required (VERSION 3.1) project (cereal) option(SKIP_PORTABILITY_TEST "Skip portability (32 bit) tests" OFF) @@ -14,6 +14,16 @@ else() set(CEREAL_THREAD_LIBS "") endif() +# Default to C++11 +if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD STREQUAL "98") + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +endif() + +if(CMAKE_CXX_STANDARD GREATER 14) + cmake_minimum_required(VERSION 3.8) +endif() + if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /W3 /WX") else() @@ -22,14 +32,6 @@ else() if(WITH_WERROR) set(CMAKE_CXX_FLAGS "-Werror ${CMAKE_CXX_FLAGS}") endif(WITH_WERROR) - if(CMAKE_VERSION VERSION_LESS 3.1) - set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") - else() - if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD STREQUAL "98") - set(CMAKE_CXX_STANDARD 11) - endif() - set(CMAKE_CXX_STANDARD_REQUIRED ON) - endif() endif() if(NOT CMAKE_VERSION VERSION_LESS 3.0) diff --git a/include/cereal/macros.hpp b/include/cereal/macros.hpp index cfdc14c59..29f3adf5b 100644 --- a/include/cereal/macros.hpp +++ b/include/cereal/macros.hpp @@ -132,4 +132,15 @@ #endif // end !defined(CEREAL_HAS_NOEXCEPT) #endif // ifndef CEREAL_NOEXCEPT +// ###################################################################### +//! Checks if C++17 is available +#if __cplusplus >= 201703L +#define CEREAL_HAS_CPP17 +#endif + +//! Checks if C++14 is available +#if __cplusplus >= 201402L +#define CEREAL_HAS_CPP14 +#endif + #endif // CEREAL_MACROS_HPP_ diff --git a/include/cereal/types/optional.hpp b/include/cereal/types/optional.hpp index 382e289a1..c3e95d916 100644 --- a/include/cereal/types/optional.hpp +++ b/include/cereal/types/optional.hpp @@ -1,6 +1,6 @@ /*! \file optional.hpp \brief Support for std::optional - \ingroup OtherTypes */ + \ingroup STLSupport */ /* Copyright (c) 2017, Juan Pedro Bolivar Puente All rights reserved. @@ -30,10 +30,11 @@ #ifndef CEREAL_TYPES_STD_OPTIONAL_ #define CEREAL_TYPES_STD_OPTIONAL_ -#include +#include "cereal/cereal.hpp" #include namespace cereal { + //! Saving for std::optional template inline void CEREAL_SAVE_FUNCTION_NAME(Archive& ar, const std::optional& optional) { @@ -45,6 +46,7 @@ namespace cereal { } } + //! Loading for std::optional template inline void CEREAL_LOAD_FUNCTION_NAME(Archive& ar, std::optional& optional) { diff --git a/include/cereal/types/variant.hpp b/include/cereal/types/variant.hpp index ded913113..137cd8972 100644 --- a/include/cereal/types/variant.hpp +++ b/include/cereal/types/variant.hpp @@ -1,6 +1,6 @@ /*! \file variant.hpp \brief Support for std::variant - \ingroup OtherTypes */ + \ingroup STLSupport */ /* Copyright (c) 2014, 2017, Randolph Voorhies, Shane Grant, Juan Pedro Bolivar Puente. All rights reserved. diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index b7a769be4..83f1cb18c 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -87,6 +87,10 @@ if(NOT MSVC) endforeach() endif(NOT MSVC) +if(CMAKE_CXX_STANDARD GREATER 14) + add_subdirectory(cpp17) +endif() + if(NOT CMAKE_VERSION VERSION_LESS 3.0) add_test(test_cmake_config_module ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake-config-module.cmake) endif() diff --git a/unittests/cpp17/CMakeLists.txt b/unittests/cpp17/CMakeLists.txt new file mode 100644 index 000000000..083979513 --- /dev/null +++ b/unittests/cpp17/CMakeLists.txt @@ -0,0 +1,38 @@ +file(GLOB TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) + +# Build all of the non-special tests +foreach(TEST_SOURCE ${TESTS}) + message(STATUS ${TEST_SOURCE}) + + string(REPLACE ".cpp" "" TEST_TARGET "${TEST_SOURCE}") + set(TEST_TARGET "test_cpp17_${TEST_TARGET}") + + add_executable(${TEST_TARGET} ${TEST_SOURCE}) + target_link_libraries(${TEST_TARGET} ${CEREAL_THREAD_LIBS}) + add_test("${TEST_TARGET}" "${TEST_TARGET}") + + # If we are on a 64-bit machine, create an extra 32-bit version of the test if portability testing is enabled + if((NOT MSVC) AND (${CMAKE_SIZEOF_VOID_P} EQUAL 8) AND (NOT SKIP_PORTABILITY_TEST)) + add_executable(${TEST_TARGET}_32 ${TEST_SOURCE}) + set_target_properties(${TEST_TARGET}_32 PROPERTIES + COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") + add_test("${TEST_TARGET}_32" "${TEST_TARGET}_32") + endif() + +endforeach() + +if(NOT MSVC) + # add tests to coverage + foreach(TEST_SOURCE ${TESTS}) + string(REPLACE ".cpp" "" COVERAGE_TARGET "${TEST_SOURCE}") + set(COVERAGE_TARGET "coverage_${COVERAGE_TARGET}") + + add_dependencies(coverage ${COVERAGE_TARGET}) + + add_executable(${COVERAGE_TARGET} EXCLUDE_FROM_ALL ${TEST_SOURCE}) + set_target_properties(${COVERAGE_TARGET} PROPERTIES COMPILE_FLAGS "-coverage") + set_target_properties(${COVERAGE_TARGET} PROPERTIES LINK_FLAGS "-coverage") + set_target_properties(${COVERAGE_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/coverage") + target_link_libraries(${COVERAGE_TARGET} ${CEREAL_THREAD_LIBS}) + endforeach() +endif(NOT MSVC) diff --git a/include/cereal/types/optional.cpp b/unittests/cpp17/optional.cpp similarity index 63% rename from include/cereal/types/optional.cpp rename to unittests/cpp17/optional.cpp index e102a167e..ed4a3d533 100644 --- a/include/cereal/types/optional.cpp +++ b/unittests/cpp17/optional.cpp @@ -26,61 +26,9 @@ */ #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "optional.hpp" -#include "common.hpp" - -#if __cplusplus >= 201703L - -#include - -template inline -void test_std_optional() -{ - std::random_device rd; - std::mt19937 gen(rd()); - - std::optional o_bv1 = random_value(gen); - std::optional o_bv2 = random_value(gen); - std::optional o_bv3 = random_basic_string(gen); - std::optional o_bv4 = std::nullopt; - std::optional o_bv5 = std::nullopt; - std::optional o_bv6 = std::nullopt; - - std::ostringstream os; - { - OArchive oar(os); - - oar(o_bv1); - oar(o_bv2); - oar(o_bv3); - oar(o_bv4); - oar(o_bv5); - oar(o_bv6); - } - - decltype(o_bv1) i_bv1; - decltype(o_bv2) i_bv2; - decltype(o_bv3) i_bv3; - decltype(o_bv4) i_bv4; - decltype(o_bv5) i_bv5; - decltype(o_bv6) i_bv6; - - std::istringstream is(os.str()); - { - IArchive iar(is); - - iar(i_bv1); - iar(i_bv2); - iar(i_bv3); - } - - CHECK_EQ( *i_bv1, std::get(o_bv1) ); - CHECK_EQ( *i_bv2, doctest::Approx(std::get(o_bv2)).epsilon(1e-5) ); - CHECK_EQ( *i_bv3, std::get(o_bv3) ); - CHECK( !i_bv4 ); - CHECK( !i_bv5 ); - CHECK( !i_bv6 ); -} +#ifdef CEREAL_HAS_CPP17 TEST_SUITE("std_optional"); @@ -106,4 +54,4 @@ TEST_CASE("json_std_optional") TEST_SUITE_END(); -#endif // is c++17 +#endif // CEREAL_HAS_CPP17 diff --git a/unittests/cpp17/optional.hpp b/unittests/cpp17/optional.hpp new file mode 100644 index 000000000..a76c19a13 --- /dev/null +++ b/unittests/cpp17/optional.hpp @@ -0,0 +1,92 @@ +/* + Copyright (c) 2017, Juan Pedro Bolivar Puente + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of cereal nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES AND SHANE GRANT BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef CEREAL_TEST_OPTIONAL_H_ +#define CEREAL_TEST_OPTIONAL_H_ +#include "../common.hpp" + +#ifdef CEREAL_HAS_CPP17 +#include + +template inline +void test_std_optional() +{ + std::random_device rd; + std::mt19937 gen(rd()); + + std::optional o_o1 = random_value(gen); + std::optional o_o2 = random_value(gen); + std::optional o_o3 = random_basic_string(gen); + std::optional o_o4 = std::nullopt; + std::optional o_o5 = std::nullopt; + std::optional o_o6 = std::nullopt; + std::optional> o_o7 = std::make_optional>( std::make_optional( random_value(gen) ) ); + + std::ostringstream os; + { + OArchive oar(os); + + oar(o_o1); + oar(o_o2); + oar(o_o3); + oar(o_o4); + oar(o_o5); + oar(o_o6); + oar(o_o7); + } + + decltype(o_o1) i_o1; + decltype(o_o2) i_o2; + decltype(o_o3) i_o3; + decltype(o_o4) i_o4; + decltype(o_o5) i_o5; + decltype(o_o6) i_o6; + decltype(o_o7) i_o7; + + std::istringstream is(os.str()); + { + IArchive iar(is); + + iar(i_o1); + iar(i_o2); + iar(i_o3); + iar(i_o4); + iar(i_o5); + iar(i_o6); + iar(i_o7); + } + + CHECK_EQ( *i_o1, *o_o1 ); + CHECK_EQ( *i_o2, doctest::Approx(*o_o2).epsilon(1e-5) ); + CHECK_EQ( *i_o3, *o_o3 ); + CHECK_EQ( *i_o4, *o_o4 ); + CHECK_EQ( *i_o5, *o_o5 ); + CHECK_EQ( *i_o6, *o_o6 ); + CHECK_EQ( **i_o7, **o_o7 ); +} + +#endif // CEREAL_HAS_CPP17 +#endif // CEREAL_TEST_OPTIONAL_H_ diff --git a/unittests/cpp17/variant.cpp b/unittests/cpp17/variant.cpp new file mode 100644 index 000000000..70f061c56 --- /dev/null +++ b/unittests/cpp17/variant.cpp @@ -0,0 +1,97 @@ +/* + Copyright (c) 2015, Kyle Fleming, Juan Pedro Bolivar Puente + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of cereal nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES AND SHANE GRANT BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN + +#include "../common.hpp" + +#if __cplusplus >= 201703L + +#include + +template inline +void test_std_variant() +{ + std::random_device rd; + std::mt19937 gen(rd()); + + std::variant o_bv1 = random_value(gen); + std::variant o_bv2 = random_value(gen); + std::variant o_bv3 = random_basic_string(gen); + + std::ostringstream os; + { + OArchive oar(os); + + oar(o_bv1); + oar(o_bv2); + oar(o_bv3); + } + + decltype(o_bv1) i_bv1; + decltype(o_bv2) i_bv2; + decltype(o_bv3) i_bv3; + + std::istringstream is(os.str()); + { + IArchive iar(is); + + iar(i_bv1); + iar(i_bv2); + iar(i_bv3); + } + + CHECK_EQ( std::get(i_bv1), std::get(o_bv1) ); + CHECK_EQ( std::get(i_bv2), doctest::Approx(std::get(o_bv2)).epsilon(1e-5) ); + CHECK_EQ( std::get(i_bv3), std::get(o_bv3) ); +} + +TEST_SUITE("std_variant"); + +TEST_CASE("binary_std_variant") +{ + test_std_variant(); +} + +TEST_CASE("portable_binary_std_variant") +{ + test_std_variant(); +} + +TEST_CASE("xml_std_variant") +{ + test_std_variant(); +} + +TEST_CASE("json_std_variant") +{ + test_std_variant(); +} + +TEST_SUITE_END(); + +#endif // is c++17 diff --git a/unittests/variant.cpp b/unittests/cpp17/variant.hpp similarity index 100% rename from unittests/variant.cpp rename to unittests/cpp17/variant.hpp