From 1bb570307df26a253777c6c6de2fdc20f7158716 Mon Sep 17 00:00:00 2001 From: Timo Koch Date: Fri, 9 Sep 2016 21:16:05 +0200 Subject: [PATCH] [io] Add function to read and write container from and to file --- dumux/io/CMakeLists.txt | 1 + dumux/io/container.hh | 69 +++++++++++++++ test/io/CMakeLists.txt | 3 +- test/io/container/CMakeLists.txt | 7 ++ test/io/container/test_container_io.cc | 116 +++++++++++++++++++++++++ 5 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 dumux/io/container.hh create mode 100644 test/io/container/CMakeLists.txt create mode 100644 test/io/container/test_container_io.cc diff --git a/dumux/io/CMakeLists.txt b/dumux/io/CMakeLists.txt index 64e7dd84f3..4ca95d9412 100644 --- a/dumux/io/CMakeLists.txt +++ b/dumux/io/CMakeLists.txt @@ -3,6 +3,7 @@ install(FILES adaptivegridrestart.hh artgridcreator.hh +container.hh cpgridcreator.hh gnuplotinterface.hh gridcreator.hh diff --git a/dumux/io/container.hh b/dumux/io/container.hh new file mode 100644 index 0000000000..5f81750cd6 --- /dev/null +++ b/dumux/io/container.hh @@ -0,0 +1,69 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program 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. * + * * + * This program 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 this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \brief Free functions to write and read a sequence container to and from a file + * \note Reading should work for all sequence containers providing begin, end, and push_back + * (e.g. std::vector, std::deque, std::list), so not for e.g. std::array. + * Writing only needs begin and end member functions returning iterators. + */ +#ifndef DUMUX_IO_CONTAINER_HH +#define DUMUX_IO_CONTAINER_HH + +#include +#include + +namespace Dumux { + +/*! + * \brief Writes a container to file + * \param v The container, requires being() and end() method + * \param filename The filename to write to + * + * \usage std::vector(5, 0.0) v; writeContainerToFile(v, "myvector.txt"); + */ +template +void writeContainerToFile(const Container& v, + const std::string& filename) +{ + std::ofstream outfile(filename, std::ios::out); + std::ostream_iterator it(outfile, "\n"); + std::copy(v.begin(),v.end(), it); +} + +/*! + * \brief Read a simple text file into a container + * \param filename The filename to write to + * \tparam Container The container type, requires being(), end(), push_back() method + * + * \usage auto v = readFileToContainer>("myvector.txt"); + */ +template +Container readFileToContainer(const std::string& filename) +{ + Container v; + std::ifstream infile(filename, std::ios::in); + std::istream_iterator it(infile); + std::copy(it, std::istream_iterator(), std::back_inserter(v)); + return v; +} + +} // end namespace Dumux + +#endif diff --git a/test/io/CMakeLists.txt b/test/io/CMakeLists.txt index 8194b9046a..ad790477b5 100644 --- a/test/io/CMakeLists.txt +++ b/test/io/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory("gnuplotinterface") -add_subdirectory("gridcreator") \ No newline at end of file +add_subdirectory("gridcreator") +add_subdirectory("container") diff --git a/test/io/container/CMakeLists.txt b/test/io/container/CMakeLists.txt new file mode 100644 index 0000000000..fd7a6fde77 --- /dev/null +++ b/test/io/container/CMakeLists.txt @@ -0,0 +1,7 @@ +add_dumux_test(test_container_io test_container_io test_container_io.cc + ${CMAKE_CURRENT_BINARY_DIR}/test_container_io) + +#install sources +install(FILES +test_container_io.cc +DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/test/io/container) diff --git a/test/io/container/test_container_io.cc b/test/io/container/test_container_io.cc new file mode 100644 index 0000000000..c5814c3f3e --- /dev/null +++ b/test/io/container/test_container_io.cc @@ -0,0 +1,116 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program 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. * + * * + * This program 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 this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \brief Test writing and reading sequence container to and from file + */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace Dumux { + +template +bool testContainerIO(const T& c0) +{ + writeContainerToFile(c0, "container.txt"); + auto c1 = readFileToContainer("container.txt"); + return std::equal(c0.begin(), c0.end(), c1.begin()); +} + +template +bool testContainerIO(const std::initializer_list& init) +{ + T c0(init); + writeContainerToFile(c0, "container.txt"); + auto c1 = readFileToContainer("container.txt"); + return std::equal(c0.begin(), c0.end(), c1.begin()); +} + +template +bool testContainerWriter(const T& c0) +{ + writeContainerToFile(c0, "container.txt"); + auto c1 = readFileToContainer>>("container.txt"); + return std::equal(c0.begin(), c0.end(), c1.begin()); +} + +} // end namespace Dumux + +//////////////////////// +// the main function +//////////////////////// +int main() +{ + bool passed = true; + + // we can read and write into + // std::vector, std::list, std::deque + // we can even read and write containers of FieldVectors (very convenient!) + auto doublei = {5.3, 6.1, 7.2, 5.66, 2.89, 8.123}; + passed = passed && Dumux::testContainerIO>(doublei); + passed = passed && Dumux::testContainerIO>(doublei); + passed = passed && Dumux::testContainerIO>(doublei); + if (!passed) return 1; + + auto inti = {5, 6, 7, 5, 2, 8}; + passed = passed && Dumux::testContainerIO>(inti); + passed = passed && Dumux::testContainerIO>(inti); + passed = passed && Dumux::testContainerIO>(inti); + if (!passed) return 1; + + std::initializer_list stringi = {"5", "6", "7", "5", "2", "8"}; + passed = passed && Dumux::testContainerIO>(stringi); + passed = passed && Dumux::testContainerIO>(stringi); + passed = passed && Dumux::testContainerIO>(stringi); + if (!passed) return 1; + + auto fvector2i = {Dune::FieldVector(0.0), Dune::FieldVector(1.0), Dune::FieldVector(2.0)}; + passed = passed && Dumux::testContainerIO>>(fvector2i); + passed = passed && Dumux::testContainerIO>>(fvector2i); + passed = passed && Dumux::testContainerIO>>(fvector2i); + if (!passed) return 1; + + auto fvector3i = {Dune::FieldVector(0.0), Dune::FieldVector(1.0), Dune::FieldVector(2.0)}; + passed = passed && Dumux::testContainerIO>>(fvector3i); + passed = passed && Dumux::testContainerIO>>(fvector3i); + passed = passed && Dumux::testContainerIO>>(fvector3i); + if (!passed) return 1; + + // we can write also std::arrays (all container providing begin and end) + passed = passed && Dumux::testContainerWriter>(std::array{1.0, 2.0}); + passed = passed && Dumux::testContainerWriter>(std::array{1, 2}); + passed = passed && Dumux::testContainerWriter>(std::array{"1.0", "2.0"}); + passed = passed && Dumux::testContainerWriter, 2>>( + std::array, 2>{Dune::FieldVector(0.0), Dune::FieldVector(1.0)}); + if (!passed) return 1; + + return 0; +} -- GitLab