From d731cd37753684248b09bb60ef829a05f1602a51 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 14 Sep 2022 11:03:20 +0200 Subject: [PATCH] import serializer code from opm-simulators add tests using a simple memcpy based packer --- CMakeLists_files.cmake | 2 + opm/common/utility/Serializer.hpp | 525 ++++++++++++++++++++++++++++++ tests/SimplePacker.hpp | 292 +++++++++++++++++ tests/test_Serialization.cpp | 321 ++++++++++++++++++ 4 files changed, 1140 insertions(+) create mode 100644 opm/common/utility/Serializer.hpp create mode 100644 tests/SimplePacker.hpp create mode 100644 tests/test_Serialization.cpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 23b05ffba..1e4de8d3f 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -375,6 +375,7 @@ if(ENABLE_ECL_INPUT) tests/test_ESmry.cpp tests/test_EInit.cpp tests/test_ExtESmry.cpp + tests/test_Serialization.cpp tests/parser/ACTIONX.cpp tests/parser/ADDREGTests.cpp tests/parser/AquiferTests.cpp @@ -635,6 +636,7 @@ list( APPEND PUBLIC_HEADER_FILES opm/common/utility/ActiveGridCells.hpp opm/common/utility/FileSystem.hpp opm/common/utility/OpmInputError.hpp + opm/common/utility/Serializer.hpp opm/common/utility/numeric/cmp.hpp opm/common/utility/platform_dependent/disable_warnings.h opm/common/utility/platform_dependent/reenable_warnings.h diff --git a/opm/common/utility/Serializer.hpp b/opm/common/utility/Serializer.hpp new file mode 100644 index 000000000..923d08b88 --- /dev/null +++ b/opm/common/utility/Serializer.hpp @@ -0,0 +1,525 @@ +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + + Consult the COPYING file in the top-level source directory of this + module for the precise wording of the license and the list of + copyright holders. +*/ +#ifndef SERIALIZER_HPP +#define SERIALIZER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Opm { +namespace detail { + +template +struct MakeVariantImpl +{ + +template +static decltype(auto) make_variant(std::size_t index) +{ + if(Index == index) + return std::variant{std::in_place_index_t{}}; + + if constexpr(sizeof...(Rest) != 0) + return make_variant(index); + else + throw std::runtime_error("Invalid variant index"); +} + +}; + +template +decltype(auto) make_variant(std::size_t index) +{ + return detail::MakeVariantImpl::template make_variant<0, Ts...>(index); +} + +template +using remove_cvr_t = std::remove_cv_t>; + +} // namespace detail + +/*! \brief Class for (de-)serializing. + *! \details If the class has a serializeOp member this is used, + * if not it is passed on to the underlying packer. +*/ + +template +class Serializer { +public: + //! \brief Constructor. + //! \param packer Packer to use + explicit Serializer(const Packer& packer) : + m_packer(packer) + {} + + //! \brief Applies current serialization op to the passed data. + template + void operator()(const T& data) + { + if constexpr (is_ptr::value) { + ptr(data); + } else if constexpr (is_pair_or_tuple::value) { + tuple(data); + } else if constexpr (is_variant::value) { + variant(data); + } else if constexpr (is_optional::value) { + optional(data); + } else if constexpr (is_vector::value) { + vector(data); + } else if constexpr (is_map::value) { + map(data); + } else if constexpr (is_array::value) { + array(data); + } else if constexpr (is_set::value) { + set(data); + } else if constexpr (has_serializeOp>::value) { + const_cast(data).serializeOp(*this); + } else { + if (m_op == Operation::PACKSIZE) + m_packSize += m_packer.packSize(data); + else if (m_op == Operation::PACK) + m_packer.pack(data, m_buffer, m_position); + else if (m_op == Operation::UNPACK) + m_packer.unpack(const_cast(data), m_buffer, m_position); + } + } + + //! \brief Call this to serialize data. + //! \tparam T Type of class to serialize + //! \param data Class to serialize + template + void pack(const T& data) + { + m_op = Operation::PACKSIZE; + m_packSize = 0; + (*this)(data); + m_position = 0; + m_buffer.resize(m_packSize); + m_op = Operation::PACK; + (*this)(data); + } + + //! \brief Call this to serialize data. + //! \tparam T Type of class to serialize + //! \param data Class to serialize + template + void pack(const Args&... data) + { + m_op = Operation::PACKSIZE; + m_packSize = 0; + variadic_call(data...); + m_position = 0; + m_buffer.resize(m_packSize); + m_op = Operation::PACK; + variadic_call(data...); + } + + //! \brief Call this to de-serialize data. + //! \tparam T Type of class to de-serialize + //! \param data Class to de-serialize + template + void unpack(T& data) + { + m_position = 0; + m_op = Operation::UNPACK; + (*this)(data); + } + + //! \brief Call this to de-serialize data. + //! \tparam T Type of class to de-serialize + //! \param data Class to de-serialize + template + void unpack(Args&... data) + { + m_position = 0; + m_op = Operation::UNPACK; + variadic_call(data...); + } + + //! \brief Returns current position in buffer. + size_t position() const + { + return m_position; + } + + //! \brief Returns true if we are currently doing a serialization operation. + bool isSerializing() const + { + return m_op != Operation::UNPACK; + } + +protected: + //! \brief Handler for vectors. + //! \tparam T Type for vector elements + //! \param data The vector to (de-)serialize + template + void vector(const std::vector& data) + { + if constexpr (std::is_pod_v) { + if (m_op == Operation::PACKSIZE) { + (*this)(data.size()); + m_packSize += m_packer.packSize(data.data(), data.size()); + } else if (m_op == Operation::PACK) { + (*this)(data.size()); + m_packer.pack(data.data(), data.size(), m_buffer, m_position); + } else if (m_op == Operation::UNPACK) { + std::size_t size = 0; + (*this)(size); + auto& data_mut = const_cast&>(data); + data_mut.resize(size); + m_packer.unpack(data_mut.data(), size, m_buffer, m_position); + } + } else { + if (m_op == Operation::UNPACK) { + std::size_t size = 0; + (*this)(size); + auto& data_mut = const_cast&>(data); + data_mut.resize(size); + std::for_each(data_mut.begin(), data_mut.end(), std::ref(*this)); + } else { + (*this)(data.size()); + std::for_each(data.begin(), data.end(), std::ref(*this)); + } + } + } + + //! \brief Handler for bool vectors. + //! \param data The vector to (de-)serialize + void vector(const std::vector& data) + { + if (m_op == Operation::UNPACK) { + std::size_t size = 0; + (*this)(size); + auto& data_mut = const_cast&>(data); + data_mut.clear(); + data_mut.reserve(size); + for (size_t i = 0; i < size; ++i) { + bool entry = false; + (*this)(entry); + data_mut.push_back(entry); + } + } else { + (*this)(data.size()); + for (const auto entry : data) { // Not a reference: vector range + bool b = entry; + (*this)(b); + } + } + } + + //! \brief Handler for arrays. + //! \param data The array to (de-)serialize + template + void array(const Array& data) + { + using T = typename Array::value_type; + + if constexpr (std::is_pod_v) { + if (m_op == Operation::PACKSIZE) + m_packSize += m_packer.packSize(data.data(), data.size()); + else if (m_op == Operation::PACK) + m_packer.pack(data.data(), data.size(), m_buffer, m_position); + else if (m_op == Operation::UNPACK) { + auto& data_mut = const_cast(data); + m_packer.unpack(data_mut.data(), data_mut.size(), m_buffer, m_position); + } + } else { + std::for_each(data.begin(), data.end(), std::ref(*this)); + } + } + + //! \brief Handler for std::variant. + //! \param data The variant to (de-)serialize + template + void variant(const std::variant& data) + { + if (m_op == Operation::UNPACK) { + std::size_t index = 0; + (*this)(index); + auto& data_mut = const_cast&>(data); + data_mut = detail::make_variant(index); + std::visit(std::ref(*this), data_mut); + } else { + (*this)(data.index()); + std::visit(std::ref(*this), data); + } + } + + //! \brief Handler for std::optional. + //! \tparam T Type for data + //! \param data The optional to (de-)serialize + template + void optional(const std::optional& data) + { + if (m_op == Operation::UNPACK) { + bool has = false; + (*this)(has); + if (has) { + T res; + (*this)(res); + const_cast&>(data) = res; + } + } else { + (*this)(data.has_value()); + if (data.has_value()) { + (*this)(*data); + } + } + } + + //! \brief Handler for std::tuple. + //! \param data The tuple to (de-)serialize + template + void tuple(const Tuple& data) + { + tuple_call(data); + } + + //! \brief Handler for maps. + //! \tparam Map map type + //! \param map The map to (de-)serialize + template + void map(const Map& data) + { + if (m_op == Operation::UNPACK) { + std::size_t size = 0; + (*this)(size); + auto& data_mut = const_cast(data); + for (size_t i = 0; i < size; ++i) { + typename Map::value_type entry; + (*this)(entry); + data_mut.insert(entry); + } + } else { + (*this)(data.size()); + std::for_each(data.begin(), data.end(), std::ref(*this)); + } + } + + //! \brief Handler for sets. + //! \tparam Set set type + //! \param data The set to (de-)serialize + template + void set(const Set& data) + { + if (m_op == Operation::UNPACK) { + std::size_t size = 0; + (*this)(size); + auto& data_mut = const_cast(data); + for (size_t i = 0; i < size; ++i) { + typename Set::value_type entry; + (*this)(entry); + data_mut.insert(entry); + } + } else { + (*this)(data.size()); + std::for_each(data.begin(), data.end(), std::ref(*this)); + } + } + + template + void variadic_call(T& first, + Args&&... args) + { + (*this)(first); + if constexpr (sizeof...(args) > 0) + variadic_call(std::forward(args)...); + } + + template + typename std::enable_if::value, void>::type + tuple_call(const Tuple&) + { + } + + template + typename std::enable_if::value, void>::type + tuple_call(const Tuple& tuple) + { + (*this)(std::get(tuple)); + tuple_call(tuple); + } + + //! \brief Enumeration of operations. + enum class Operation { + PACKSIZE, //!< Calculating serialization buffer size + PACK, //!< Performing serialization + UNPACK //!< Performing de-serialization + }; + + //! \brief Predicate for detecting vectors. + template + struct is_vector { + constexpr static bool value = false; + }; + + template + struct is_vector> { + constexpr static bool value = true; + }; + + //! \brief Predicate for detecting variants. + template + struct is_variant { + constexpr static bool value = false; + }; + + template + struct is_variant> { + constexpr static bool value = true; + }; + + //! \brief Predicate for detecting pairs and tuples. + template + struct is_pair_or_tuple { + constexpr static bool value = false; + }; + + template + struct is_pair_or_tuple> { + constexpr static bool value = true; + }; + + template + struct is_pair_or_tuple> { + constexpr static bool value = true; + }; + + //! \brief Predicate for smart pointers. + template + struct is_ptr { + constexpr static bool value = false; + }; + + template + struct is_ptr> { + constexpr static bool value = true; + }; + + template + struct is_ptr> { + constexpr static bool value = true; + }; + + //! \brief Predicate for std::optional. + template + struct is_optional { + constexpr static bool value = false; + }; + + template + struct is_optional> { + constexpr static bool value = true; + }; + + //! \brief Predicate for maps + template + struct is_map { + constexpr static bool value = false; + }; + + template + struct is_map> { + constexpr static bool value = true; + }; + + template + struct is_map> { + constexpr static bool value = true; + }; + + //! \brief Predicate for sets + template + struct is_set { + constexpr static bool value = false; + }; + + template + struct is_set> { + constexpr static bool value = true; + }; + + template + struct is_set> { + constexpr static bool value = true; + }; + + //! \brief Predicate for arrays + template + struct is_array { + constexpr static bool value = false; + }; + + template + struct is_array> { + constexpr static bool value = true; + }; + + //! Detect existence of \c serializeOp member function + //! + //! Base case (no \c serializeOp member function) + template + struct has_serializeOp : public std::false_type {}; + + //! Detect existence of \c serializeOp member function + //! + //! Non-default, albeit common, case (type has \c serializeOp member + //! function) + template + struct has_serializeOp< + T, std::void_t().serializeOp(std::declval&>()))> + > : public std::true_type {}; + + //! \brief Handler for smart pointers. + template + void ptr(const PtrType& data) + { + using T1 = typename PtrType::element_type; + bool value = data ? true : false; + (*this)(value); + if (m_op == Operation::UNPACK && value) { + const_cast(data).reset(new T1); + } + if (data) { + (*this)(*data); + } + } + + const Packer& m_packer; //!< Packer to use + Operation m_op = Operation::PACKSIZE; //!< Current operation + size_t m_packSize = 0; //!< Required buffer size after PACKSIZE has been done + int m_position = 0; //!< Current position in buffer + std::vector m_buffer; //!< Buffer for serialized data +}; + +} + +#endif diff --git a/tests/SimplePacker.hpp b/tests/SimplePacker.hpp new file mode 100644 index 000000000..709acf1a5 --- /dev/null +++ b/tests/SimplePacker.hpp @@ -0,0 +1,292 @@ +/* + Copyright 2019 Equinor AS. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ +#ifndef SIMPLE_PACKER_HPP +#define SIMPLE_PACKER_HPP + +#include + +#include +#include +#include +#include + +namespace Opm { +namespace TestUtil { +namespace detail { + +//! \brief Abstract struct for packing which is (partially) specialized for specific types. +template +struct Packing +{ + static std::size_t packSize(const T&); + static void pack(const T&, std::vector&, int&); + static void unpack(T&, std::vector&, int&); +}; + +//! \brief Packaging for pod data. +template +struct Packing +{ + //! \brief Calculates the pack size for a POD. + //! \param data The data to pack + static std::size_t packSize(const T& data) + { + return packSize(&data, 1); + } + + //! \brief Calculates the pack size for an array of POD. + //! \param data The array to pack + //! \param n Length of array + static std::size_t packSize(const T*, std::size_t n) + { + return n*sizeof(T); + } + + //! \brief Pack a POD. + //! \param data The variable to pack + //! \param buffer Buffer to pack into + //! \param position Position in buffer to use + static void pack(const T& data, + std::vector& buffer, + int& position) + { + pack(&data, 1, buffer, position); + } + + //! \brief Pack an array of POD. + //! \param data The array to pack + //! \param n Length of array + //! \param buffer Buffer to pack into + //! \param position Position in buffer to use + static void pack(const T* data, + std::size_t n, + std::vector& buffer, + int& position) + { + std::memcpy(&buffer[position], data, n*sizeof(T)); + position += n*sizeof(T); + } + + //! \brief Unpack a POD. + //! \param data The variable to unpack + //! \param buffer Buffer to unpack from + //! \param position Position in buffer to use + static void unpack(T& data, + std::vector& buffer, + int& position) + { + unpack(&data, 1, buffer, position); + } + + //! \brief Unpack an array of POD. + //! \param data The array to unpack + //! \param n Length of array + //! \param buffer Buffer to unpack from + //! \param position Position in buffer to use + static void unpack(T* data, + std::size_t n, + std::vector& buffer, + int& position) + { + std::memcpy(data, &buffer[position], n*sizeof(T)); + position += n*sizeof(T); + } +}; + +//! \brief Default handling for unsupported types. +template +struct Packing +{ + static std::size_t packSize(const T&) + { + static_assert(!std::is_same_v, "Packing not supported for type"); + return 0; + } + + static void pack(const T&, std::vector&, int&) + { + static_assert(!std::is_same_v, "Packing not supported for type"); + } + + static void unpack(T&, std::vector&, int&) + { + static_assert(!std::is_same_v, "Packing not supported for type"); + } +}; + +//! \brief Specialization for std::bitset +template +struct Packing> +{ + static std::size_t packSize(const std::bitset& data) + { + return Packing::packSize(data.to_ullong()); + } + + static void pack(const std::bitset& data, + std::vector& buffer, int& position) + { + Packing::pack(data.to_ullong(), buffer, position); + } + + static void unpack(std::bitset& data, + std::vector& buffer, int& position) + { + unsigned long long d; + Packing::unpack(d, buffer, position); + data = std::bitset(d); + } +}; + +template<> +struct Packing +{ + static std::size_t packSize(const std::string& data) + { + return sizeof(std::size_t) + data.size(); + } + + static void pack(const std::string& data, + std::vector& buffer, int& position) + { + Packing::pack(data.size(), buffer, position); + Packing::pack(data.data(), data.size(), buffer, position); + } + + static void unpack(std::string& data, std::vector& buffer, int& position) + { + std::size_t length = 0; + Packing::unpack(length, buffer, position); + std::vector cStr(length+1, '\0'); + Packing::unpack(cStr.data(), length, buffer, position); + data.clear(); + data.append(cStr.data(), length); + } +}; + +template<> +struct Packing +{ + static std::size_t packSize(const time_point&) + { + return Packing::packSize(std::time_t()); + } + + static void pack(const time_point& data, + std::vector& buffer, int& position) + { + Packing::pack(TimeService::to_time_t(data), + buffer, position); + } + + static void unpack(time_point& data, std::vector& buffer, int& position) + { + std::time_t res; + Packing::unpack(res, buffer, position); + data = TimeService::from_time_t(res); + } +}; + +} + +//! \brief Struct handling packing of serialization for test purposes. +struct Packer { + //! \brief Calculates the pack size for a variable. + //! \tparam T The type of the data to be packed + //! \param data The data to pack + template + std::size_t packSize(const T& data) const + { + return detail::Packing,T>::packSize(data); + } + + //! \brief Calculates the pack size for an array. + //! \tparam T The type of the data to be packed + //! \param data The array to pack + //! \param n Length of array + template + std::size_t packSize(const T* data, std::size_t n) const + { + static_assert(std::is_pod_v, "Array packing not supported for non-pod data"); + return detail::Packing::packSize(data, n); + } + + //! \brief Pack a variable. + //! \tparam T The type of the data to be packed + //! \param data The variable to pack + //! \param buffer Buffer to pack into + //! \param position Position in buffer to use + template + void pack(const T& data, + std::vector& buffer, + int& position) const + { + detail::Packing,T>::pack(data, buffer, position); + } + + //! \brief Pack an array. + //! \tparam T The type of the data to be packed + //! \param data The array to pack + //! \param n Length of array + //! \param buffer Buffer to pack into + //! \param position Position in buffer to use + template + void pack(const T* data, + std::size_t n, + std::vector& buffer, + int& position) const + { + static_assert(std::is_pod_v, "Array packing not supported for non-pod data"); + detail::Packing::pack(data, n, buffer, position); + } + + //! \brief Unpack a variable. + //! \tparam T The type of the data to be unpacked + //! \param data The variable to unpack + //! \param buffer Buffer to unpack from + //! \param position Position in buffer to use + template + void unpack(T& data, + std::vector& buffer, + int& position) const + { + detail::Packing,T>::unpack(data, buffer, position); + } + + //! \brief Unpack an array. + //! \tparam T The type of the data to be unpacked + //! \param data The array to unpack + //! \param n Length of array + //! \param buffer Buffer to unpack from + //! \param position Position in buffer to use + template + void unpack(T* data, + std::size_t n, + std::vector& buffer, + int& position) const + { + static_assert(std::is_pod_v, "Array packing not supported for non-pod data"); + detail::Packing::unpack(data, n, buffer, position); + } +}; + +} // end namespace TestUtil +} // end namespace Opm + +#endif // SIMPLE_PACKER_HPP diff --git a/tests/test_Serialization.cpp b/tests/test_Serialization.cpp new file mode 100644 index 000000000..c015a3dc4 --- /dev/null +++ b/tests/test_Serialization.cpp @@ -0,0 +1,321 @@ +/* + Copyright 2019 SINTEF Digital, Mathematics and Cybernetics. + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#include + +#define BOOST_TEST_MODULE TestSerialization +#define BOOST_TEST_NO_MAIN + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "SimplePacker.hpp" + +template +std::tuple PackUnpack(T& in) +{ + Opm::TestUtil::Packer packer; + Opm::Serializer ser(packer); + ser.pack(in); + size_t pos1 = ser.position(); + T out; + ser.unpack(out); + size_t pos2 = ser.position(); + + return std::make_tuple(out, pos1, pos2); +} + + +#define TEST_FOR_TYPE_NAMED_OBJ(TYPE, NAME, OBJ) \ +BOOST_AUTO_TEST_CASE(NAME) \ +{ \ + auto val1 = Opm::TYPE::OBJ(); \ + auto val2 = PackUnpack(val1); \ + BOOST_CHECK_MESSAGE(std::get<1>(val2) == std::get<2>(val2), "Packed size differ from unpack size for " #TYPE); \ + BOOST_CHECK_MESSAGE(val1 == std::get<0>(val2), "Deserialized " #TYPE " differ"); \ +} + +#define TEST_FOR_TYPE_NAMED(TYPE, NAME) \ + TEST_FOR_TYPE_NAMED_OBJ(TYPE, NAME, serializeObject) + +#define TEST_FOR_TYPE(TYPE) \ + TEST_FOR_TYPE_NAMED(TYPE, TYPE) + + +TEST_FOR_TYPE(Actdims) +TEST_FOR_TYPE(Aqudims) +TEST_FOR_TYPE(Aquancon) +TEST_FOR_TYPE(AquiferConfig) +TEST_FOR_TYPE(AquiferCT) +TEST_FOR_TYPE(Aquifetp) +TEST_FOR_TYPE(AutoICD) +TEST_FOR_TYPE_NAMED(Action::Actions, Actions) +TEST_FOR_TYPE_NAMED(Action::ActionX, ActionX) +TEST_FOR_TYPE_NAMED(Action::AST, ActionAST) +TEST_FOR_TYPE_NAMED(Action::ASTNode, ActionASTNode) +TEST_FOR_TYPE_NAMED(Action::State, ActionState) +TEST_FOR_TYPE(BCConfig) +TEST_FOR_TYPE(BrineDensityTable) +TEST_FOR_TYPE(ColumnSchema) +TEST_FOR_TYPE(Connection) +TEST_FOR_TYPE_NAMED_OBJ(data::AquiferData, AquiferData_CarterTracy, serializeObjectC) +TEST_FOR_TYPE_NAMED_OBJ(data::AquiferData, AquiferData_Fetkovich, serializeObjectF) +TEST_FOR_TYPE_NAMED_OBJ(data::AquiferData, AquiferData_Numeric, serializeObjectN) +TEST_FOR_TYPE_NAMED(data::CarterTracyData, CarterTracyData) +TEST_FOR_TYPE_NAMED(data::CellData, CellData) +TEST_FOR_TYPE_NAMED(data::Connection, dataConnection) +TEST_FOR_TYPE_NAMED(data::CurrentControl, CurrentControl) +TEST_FOR_TYPE_NAMED(data::FetkovichData, FetkovichData) +TEST_FOR_TYPE_NAMED(data::GroupAndNetworkValues, GroupAndNetworkValues) +TEST_FOR_TYPE_NAMED(data::GroupConstraints, GroupConstraints) +TEST_FOR_TYPE_NAMED(data::GroupData, GroupData) +TEST_FOR_TYPE_NAMED(data::GroupGuideRates, GroupGuideRates) +TEST_FOR_TYPE_NAMED(data::GuideRateValue, GuideRateValue) +TEST_FOR_TYPE_NAMED(data::NodeData, NodeData) +TEST_FOR_TYPE_NAMED(data::NumericAquiferData, NumericAquiferData) +TEST_FOR_TYPE_NAMED(data::Rates, Rates) +TEST_FOR_TYPE_NAMED(data::Segment, dataSegment) +TEST_FOR_TYPE_NAMED(data::SegmentPressures, SegmentPressures) +TEST_FOR_TYPE_NAMED(data::Solution, Solution) +TEST_FOR_TYPE_NAMED(data::Well, dataWell) +TEST_FOR_TYPE_NAMED(data::Wells, Wells) +TEST_FOR_TYPE(Deck) +TEST_FOR_TYPE(DeckItem) +TEST_FOR_TYPE(DeckKeyword) +TEST_FOR_TYPE(DeckRecord) +TEST_FOR_TYPE(DensityTable) +TEST_FOR_TYPE(DenT) +TEST_FOR_TYPE(Dimension) +TEST_FOR_TYPE(EclHysterConfig) +TEST_FOR_TYPE(EclipseConfig) +TEST_FOR_TYPE(EndpointScaling) +TEST_FOR_TYPE(Eqldims) +TEST_FOR_TYPE(Equil) +TEST_FOR_TYPE(TLMixpar) +TEST_FOR_TYPE(Events) +TEST_FOR_TYPE(Fault) +TEST_FOR_TYPE(FaultCollection) +TEST_FOR_TYPE(FaultFace) +TEST_FOR_TYPE_NAMED(Fieldprops::TranCalculator, TranCalculator) +TEST_FOR_TYPE(FoamConfig) +TEST_FOR_TYPE(FoamData) +TEST_FOR_TYPE(GConSale) +TEST_FOR_TYPE(GConSump) +TEST_FOR_TYPE(GridDims) +TEST_FOR_TYPE(Group) +TEST_FOR_TYPE_NAMED(Group::GroupInjectionProperties, GroupInjectionProperties) +TEST_FOR_TYPE_NAMED(Group::GroupProductionProperties, GroupProductionProperties) +TEST_FOR_TYPE(GuideRateConfig) +TEST_FOR_TYPE(GuideRateModel) +TEST_FOR_TYPE(InitConfig) +TEST_FOR_TYPE(IOConfig) +TEST_FOR_TYPE(JFunc) +TEST_FOR_TYPE(KeywordLocation) +TEST_FOR_TYPE(MessageLimits) +TEST_FOR_TYPE(MULTREGTScanner) +TEST_FOR_TYPE(NNC) +TEST_FOR_TYPE_NAMED(Network::Node, NetworkNode) +TEST_FOR_TYPE(OilVaporizationProperties) +TEST_FOR_TYPE(PAvg) +TEST_FOR_TYPE(Phases) +TEST_FOR_TYPE(PlymwinjTable) +TEST_FOR_TYPE(PlyshlogTable) +TEST_FOR_TYPE(PvcdoTable) +TEST_FOR_TYPE(PvtgTable) +TEST_FOR_TYPE(PvtoTable) +TEST_FOR_TYPE(PvtwsaltTable) +TEST_FOR_TYPE(PvtwTable) +TEST_FOR_TYPE(Regdims) +TEST_FOR_TYPE(RestartKey) +TEST_FOR_TYPE(RestartValue) +TEST_FOR_TYPE(RSTConfig) +TEST_FOR_TYPE(RFTConfig) +TEST_FOR_TYPE(RockConfig) +TEST_FOR_TYPE(RockTable) +TEST_FOR_TYPE(RocktabTable) +TEST_FOR_TYPE(Rock2dtrTable) +TEST_FOR_TYPE(Rock2dTable) +TEST_FOR_TYPE(Runspec) +TEST_FOR_TYPE(Schedule) +TEST_FOR_TYPE(ScheduleDeck) +TEST_FOR_TYPE(Segment) +TEST_FOR_TYPE(SimpleTable) +TEST_FOR_TYPE(SimulationConfig) +TEST_FOR_TYPE(SkprpolyTable) +TEST_FOR_TYPE(SkprwatTable) +TEST_FOR_TYPE(SICD) +TEST_FOR_TYPE(SolventDensityTable) +TEST_FOR_TYPE(SummaryConfig) +TEST_FOR_TYPE(SummaryConfigNode) +TEST_FOR_TYPE(SummaryState) +TEST_FOR_TYPE(Tabdims) +TEST_FOR_TYPE(TableColumn) +TEST_FOR_TYPE(TableContainer) +TEST_FOR_TYPE(TableManager) +TEST_FOR_TYPE(TableSchema) +TEST_FOR_TYPE(ThresholdPressure) +TEST_FOR_TYPE(TracerConfig) +TEST_FOR_TYPE(TransMult) +TEST_FOR_TYPE(Tuning) +TEST_FOR_TYPE(UDAValue) +TEST_FOR_TYPE(UDQAssign) +TEST_FOR_TYPE(UDQActive) +TEST_FOR_TYPE(UDQASTNode) +TEST_FOR_TYPE(UDQConfig) +TEST_FOR_TYPE(UDQDefine) +TEST_FOR_TYPE(UDQIndex) +TEST_FOR_TYPE(UDQParams) +TEST_FOR_TYPE(UDQState) +TEST_FOR_TYPE(UnitSystem) +TEST_FOR_TYPE(Valve) +TEST_FOR_TYPE(VFPInjTable) +TEST_FOR_TYPE(VFPProdTable) +TEST_FOR_TYPE(ViscrefTable) +TEST_FOR_TYPE(WatdentTable) +TEST_FOR_TYPE(Well) +TEST_FOR_TYPE(Welldims) +TEST_FOR_TYPE(WellBrineProperties) +TEST_FOR_TYPE(WellConnections) +TEST_FOR_TYPE(WellEconProductionLimits) +TEST_FOR_TYPE(WellFoamProperties) +TEST_FOR_TYPE_NAMED(Well::WellGuideRate, WellGuideRate) +TEST_FOR_TYPE_NAMED(Well::WellInjectionProperties, WellInjectionProperties) +TEST_FOR_TYPE(WellPolymerProperties) +TEST_FOR_TYPE_NAMED(Well::WellProductionProperties, WellProductionProperties) +TEST_FOR_TYPE(WellTracerProperties) +TEST_FOR_TYPE(WellSegmentDims) +TEST_FOR_TYPE(WellSegments) +TEST_FOR_TYPE(WellTestConfig) +TEST_FOR_TYPE(WellTestState) +TEST_FOR_TYPE(WellType) +TEST_FOR_TYPE(WListManager) +TEST_FOR_TYPE(WriteRestartFileEvents) + + +bool init_unit_test_func() +{ + return true; +} + + +int main(int argc, char** argv) +{ + return boost::unit_test::unit_test_main(&init_unit_test_func, argc, argv); +}