Commit 22180104 authored by GILLES Sebastien's avatar GILLES Sebastien

#1469 Provide a naive and not DRY way to use PrintContainer() upon a container of (some) variants.

parent 71033460
......@@ -3424,6 +3424,8 @@
BE353BA322E76CF500A06A8F /* ConvertEntryToString.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ConvertEntryToString.cpp; sourceTree = "<group>"; };
BE353BA422E76CF500A06A8F /* ConvertEntryToString.hxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ConvertEntryToString.hxx; sourceTree = "<group>"; };
BE353BA522E76CF500A06A8F /* ConvertEntryToString.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ConvertEntryToString.hpp; sourceTree = "<group>"; };
BE353BAA22E77F5C00A06A8F /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
BE353BAB22E77F5C00A06A8F /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
BE372DDB18C4802900127212 /* main_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main_test.cpp; sourceTree = "<group>"; };
BE37EFEB1CB308340006C0AD /* FiniteElement.doxygen */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = FiniteElement.doxygen; sourceTree = "<group>"; };
BE390F142108C9BD0049CD3B /* test_input_data.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = test_input_data.cpp; sourceTree = "<group>"; };
......@@ -6579,6 +6581,7 @@
BEDFFB7B204EE4F400A52F86 /* TypeName */,
BECEF93222DF63CA00D0DDE7 /* Now */,
BE2457AB1E005B0B00677AEF /* InputData */,
BE353BA922E77F0700A06A8F /* PrintContainer */,
);
path = Utilities;
sourceTree = "<group>";
......@@ -6799,6 +6802,15 @@
path = ConvertEntryToString;
sourceTree = "<group>";
};
BE353BA922E77F0700A06A8F /* PrintContainer */ = {
isa = PBXGroup;
children = (
BE353BAB22E77F5C00A06A8F /* CMakeLists.txt */,
BE353BAA22E77F5C00A06A8F /* main.cpp */,
);
path = PrintContainer;
sourceTree = "<group>";
};
BE372DCD18C47F0500127212 /* Test */ = {
isa = PBXGroup;
children = (
......@@ -4,6 +4,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/TupleHasType/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/LuaOptionFile/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/TypeName/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/Now/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/PrintContainer/CMakeLists.txt)
# Needs to be incorporated (or dropped) - see #1272
# include(${CMAKE_CURRENT_LIST_DIR}/InputData/CMakeLists.txt)
......
add_executable(MoReFEMTestPrintContainer
${CMAKE_CURRENT_LIST_DIR}/main.cpp
)
target_link_libraries(MoReFEMTestPrintContainer
${MOREFEM_TEST_TOOLS}
)
add_test(PrintContainer
MoReFEMTestPrintContainer
--
${MOREFEM_ROOT}
${MOREFEM_TEST_OUTPUT_DIR})
set_tests_properties(PrintContainer PROPERTIES TIMEOUT 4)
/*!
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Fri, 6 Apr 2018 18:06:38 +0200
// Copyright (c) Inria. All rights reserved.
//
*/
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <deque>
#define BOOST_TEST_MODULE print_containers
#include "ThirdParty/IncludeWithoutWarning/Boost/Test.hpp"
#include "Utilities/Containers/Print.hpp"
using namespace MoReFEM;
PRAGMA_DIAGNOSTIC(push)
# ifdef __clang__
PRAGMA_DIAGNOSTIC(ignored "-Wdisabled-macro-expansion")
# endif // __clang__
BOOST_AUTO_TEST_CASE(vector_simple)
{
std::vector<int> a { 5, 7, -4, 3 };
std::ostringstream oconv;
Utilities::PrintContainer(a, oconv);
BOOST_CHECK_EQUAL(oconv.str(), "[5, 7, -4, 3]\n");
}
BOOST_AUTO_TEST_CASE(deque_custom)
{
std::deque<std::string> a { "Not", "a", "hello", "world" };
std::ostringstream oconv;
Utilities::PrintContainer(a, oconv, ' ', "", '!');
BOOST_CHECK_EQUAL(oconv.str(), "Not a hello world!");
}
BOOST_AUTO_TEST_CASE(vector_of_simple_variant)
{
using variant = std::variant<int, double, std::string>;
std::vector<variant> a { 4.3, 3, "Hello", -6, "Bye!" };
std::ostringstream oconv;
Utilities::PrintContainer(a, oconv, ", ", "{", '}');
BOOST_CHECK_EQUAL(oconv.str(), "{4.3, 3, Hello, -6, Bye!}");
}
PRAGMA_DIAGNOSTIC(pop)
......@@ -20,9 +20,12 @@
# include <cassert>
# include <iosfwd>
# include <tuple>
# include <map>
# include <variant>
# include <iostream> // mandatory due to std::cout as default parameter
# include "Utilities/String/Traits.hpp"
# include "Utilities/Miscellaneous.hpp"
namespace MoReFEM
......@@ -37,7 +40,7 @@ namespace MoReFEM
* \brief Print the content of a non associative container (list, vector, deque, array, etc...)
*
* \tparam StreamT Type of output stream considered
* \tparam ContainerT Type of the container to be displayed
* \tparam ContainerT Type of the container to be displayed. This might be a container of std::variant!
*
* \param[in,out] stream Output stream in which container will be displayed
* \param[in] container Container displayed
......@@ -75,11 +78,72 @@ namespace MoReFEM
for (decltype(size) i = 0u; i + 1u < size; ++it, ++i)
{
assert(it != end);
stream << *it << separator;
// If one of the element is a std::variant, it may be printed... provided the type within the
// variant overloas properly operator<< !
if constexpr (Utilities::IsSpecializationOf
<
std::variant,
typename ContainerT::value_type
>())
{
std::visit([&stream](auto&& arg)
{
using type_arg = std::decay_t<decltype(arg)>;
if constexpr (Utilities::IsSpecializationOf
<
std::map,
type_arg
>())
{
stream << "Map!";
}
else if constexpr (std::is_same_v<type_arg, std::nullptr_t>)
stream << "Nullptr!";
else
stream << arg;
},
*it);
}
else
stream << *it;
stream << separator;
}
if (size > 0u)
stream << *it;
{
// TMP: this is not DRY !!!
if constexpr (Utilities::IsSpecializationOf
<
std::variant,
typename ContainerT::value_type
>())
{
std::visit([&stream](auto&& arg)
{
using type_arg = std::decay_t<decltype(arg)>;
if constexpr (Utilities::IsSpecializationOf
<
std::map,
type_arg
>())
{
stream << "Map!";
}
else if constexpr (std::is_same_v<type_arg, std::nullptr_t>)
stream << "Nullptr!";
else
stream << arg;
},
*it);
}
else
stream << *it;
}
stream << closer;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment