From 005d628652a71bbd0caa6cf5ee5e5dcfa59bed0a Mon Sep 17 00:00:00 2001 From: ilerik Date: Sat, 18 Apr 2015 17:50:59 +0300 Subject: [PATCH] Added support for std::valarray. 1) Implemented std::valarray serialization (based on vector.hpp) in file valarray.hpp 2) Implemented unit tests in file valarray.cpp (based on vector.cpp tests, except for bool case) 3) vs2013/unittests project configuration updated accordingly 4) unittests/common.hpp updated. 5) No documentation so far --- include/cereal/types/valarray.hpp | 103 ++++++++++++++++++ unittests/common.hpp | 1 + unittests/valarray.cpp | 120 +++++++++++++++++++++ vs2013/unittests/unittests.vcxproj | 7 +- vs2013/unittests/unittests.vcxproj.filters | 5 +- 5 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 include/cereal/types/valarray.hpp create mode 100644 unittests/valarray.cpp diff --git a/include/cereal/types/valarray.hpp b/include/cereal/types/valarray.hpp new file mode 100644 index 00000000..ca743bb0 --- /dev/null +++ b/include/cereal/types/valarray.hpp @@ -0,0 +1,103 @@ +/*! \file valarray.hpp +\brief Support for types found in \ +\ingroup STLSupport */ + +/* +Copyright (c) 2014, Randolph Voorhies, Shane Grant +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 OR 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_TYPES_VALARRAY_HPP_ +#define CEREAL_TYPES_VALARRAY_HPP_ + +#include +#include + +namespace cereal +{ + /* Implementation note + Since valarray can only contain arithmetic types, pointer or other valarrays we need to define serialization for all the cases mentioned + Following implementation in valarray.hpp we get serialization for std::valarray arithmetic values directly and all other cases implemented as calls + for underlying serialization of every valarray element. */ + + //! Saving for std::valarray arithmetic types + //! using binary serialization, if supported + template inline + typename std::enable_if, Archive>::value + && std::is_arithmetic::value, void>::type + CEREAL_SAVE_FUNCTION_NAME(Archive & ar, std::valarray const & valarray) + { + size_type valarraySize = static_cast(valarray.size()); //get valarray size + ar(make_size_tag(valarraySize)); // save number of elements + if (valarraySize > 0) { // save data if it's not empty + ar(binary_data(&valarray[0], static_cast(valarraySize) * sizeof(T))); // &valarray[0] applicable since std::valarray guaranteed to be stored contignously + } + } + + //! Loading for std::valarray arithmetic types + //! using binary serialization, if supported + template inline + typename std::enable_if, Archive>::value + && std::is_arithmetic::value, void>::type + CEREAL_LOAD_FUNCTION_NAME(Archive & ar, std::valarray & valarray) + { + size_type valarraySize; + ar(make_size_tag(valarraySize)); + + valarray.resize(static_cast(valarraySize)); + if (valarraySize > 0) { // load data if it's not empty + ar( binary_data(&valarray[0], static_cast(valarraySize) * sizeof(T)) ); + } + } + + //! Saving for std::valarray all other types + template inline + typename std::enable_if, Archive>::value + || !std::is_arithmetic::value, void>::type + CEREAL_SAVE_FUNCTION_NAME(Archive & ar, std::valarray const & valarray) + { + ar(make_size_tag(static_cast(valarray.size()))); // number of elements + for (auto const & i : valarray) + ar(i); + } + + //! Loading for std::valarray all other types + template inline + typename std::enable_if, Archive>::value + || !std::is_arithmetic::value, void>::type + CEREAL_LOAD_FUNCTION_NAME(Archive & ar, std::valarray & valarray) + { + size_type valarraySize; + ar(make_size_tag(valarraySize)); + + valarray.resize(static_cast(valarraySize)); + if (valarraySize > 0) { // load data if it's not empty + for (auto & i : valarray) + ar(i); + } + } +} // namespace cereal + +#endif // CEREAL_TYPES_VALARRAY_HPP_ diff --git a/unittests/common.hpp b/unittests/common.hpp index 258fc365..d3e58c96 100644 --- a/unittests/common.hpp +++ b/unittests/common.hpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/unittests/valarray.cpp b/unittests/valarray.cpp new file mode 100644 index 00000000..b1bc3c74 --- /dev/null +++ b/unittests/valarray.cpp @@ -0,0 +1,120 @@ +/* +Copyright (c) 2014, Randolph Voorhies, Shane Grant +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. +*/ +#include "common.hpp" +#include + +template +void test_valarray() +{ + std::random_device rd; + std::mt19937 gen(rd()); + + for (int ii = 0; ii<100; ++ii) + { + std::valarray o_podvalarray(100); + for (auto & elem : o_podvalarray) + elem = random_value(gen); + + std::valarray o_iservalarray(100); + for (auto & elem : o_iservalarray) + elem = StructInternalSerialize(random_value(gen), random_value(gen)); + + std::valarray o_isplvalarray(100); + for (auto & elem : o_isplvalarray) + elem = StructInternalSplit(random_value(gen), random_value(gen)); + + std::valarray o_eservalarray(100); + for (auto & elem : o_eservalarray) + elem = StructExternalSerialize(random_value(gen), random_value(gen)); + + std::valarray o_esplvalarray(100); + for (auto & elem : o_esplvalarray) + elem = StructExternalSplit(random_value(gen), random_value(gen)); + + std::ostringstream os; + { + OArchive oar(os); + + oar(o_podvalarray); + oar(o_iservalarray); + oar(o_isplvalarray); + oar(o_eservalarray); + oar(o_esplvalarray); + } + + std::valarray i_podvalarray; + std::valarray i_iservalarray; + std::valarray i_isplvalarray; + std::valarray i_eservalarray; + std::valarray i_esplvalarray; + + std::istringstream is(os.str()); + { + IArchive iar(is); + + iar(i_podvalarray); + iar(i_iservalarray); + iar(i_isplvalarray); + iar(i_eservalarray); + iar(i_esplvalarray); + } + + BOOST_CHECK_EQUAL(i_podvalarray.size(), o_podvalarray.size()); + BOOST_CHECK_EQUAL(i_iservalarray.size(), o_iservalarray.size()); + BOOST_CHECK_EQUAL(i_isplvalarray.size(), o_isplvalarray.size()); + BOOST_CHECK_EQUAL(i_eservalarray.size(), o_eservalarray.size()); + BOOST_CHECK_EQUAL(i_esplvalarray.size(), o_esplvalarray.size()); + + BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(i_podvalarray), std::end(i_podvalarray), std::begin(o_podvalarray), std::end(o_podvalarray)); + BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(i_iservalarray), std::end(i_iservalarray), std::begin(o_iservalarray), std::end(o_iservalarray)); + BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(i_isplvalarray), std::end(i_isplvalarray), std::begin(o_isplvalarray), std::end(o_isplvalarray)); + BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(i_eservalarray), std::end(i_eservalarray), std::begin(o_eservalarray), std::end(o_eservalarray)); + BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(i_esplvalarray), std::end(i_esplvalarray), std::begin(o_esplvalarray), std::end(o_esplvalarray)); + } +} + +BOOST_AUTO_TEST_CASE(binary_valarray) +{ + test_valarray(); +} + +BOOST_AUTO_TEST_CASE(portable_binary_valarray) +{ + test_valarray(); +} + +BOOST_AUTO_TEST_CASE(xml_valarray) +{ + test_valarray(); +} + +BOOST_AUTO_TEST_CASE(json_valarray) +{ + test_valarray(); +} + + diff --git a/vs2013/unittests/unittests.vcxproj b/vs2013/unittests/unittests.vcxproj index 8e615f5a..951f45ba 100644 --- a/vs2013/unittests/unittests.vcxproj +++ b/vs2013/unittests/unittests.vcxproj @@ -1,4 +1,4 @@ - + @@ -52,6 +52,7 @@ + @@ -103,7 +104,7 @@ - $(SolutionDir)\..\include;$(SolutionDir)\..\unittests;E:\Boost\include\boost-1_55;$(IncludePath) + $(SolutionDir)\..\include;$(SolutionDir)\..\unittests;D:\Libs\boost_1_58_0;$(IncludePath) E:\Boost\lib;$(LibraryPath) @@ -111,7 +112,7 @@ E:\Boost\lib\x64;$(LibraryPath) - $(SolutionDir)\..\include;$(SolutionDir)\..\unittests;E:\Boost\include\boost-1_55;$(IncludePath) + $(SolutionDir)\..\include;$(SolutionDir)\..\unittests;D:\Libs\boost_1_58_0;$(IncludePath) E:\Boost\lib;$(LibraryPath) diff --git a/vs2013/unittests/unittests.vcxproj.filters b/vs2013/unittests/unittests.vcxproj.filters index f4d3d90a..902b5351 100644 --- a/vs2013/unittests/unittests.vcxproj.filters +++ b/vs2013/unittests/unittests.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -110,6 +110,9 @@ Source Files + + + Source Files Source Files