Commit ffe08886 authored by Tomáš Jakubec's avatar Tomáš Jakubec
Browse files

SelectTraits handles zero number of arguments too by returning the default traits.

VTKMeshDataReader and VTKMeshDataWriter are able to able to work with tuple of traits.
parent 48041d39
Pipeline #2294 failed with stage
in 16 seconds
......@@ -15,10 +15,14 @@ struct IsTraitsOf<Class, Traits<Class, TraitsArgs...>> : public std::true_type {
/**
* This class selects the first class traits with respect
* to Class.
* to Class. If none type of traits is given, it returns
* DefaultIOTraits<Class> if possible.
*/
template <typename Class, size_t Index, typename... TraitsTypes>
struct SelectTraits{};
template <typename Class, size_t Index, typename TraitsType, typename... TraitsTypes>
struct SelectTraits : public
struct SelectTraits<Class, Index, TraitsType, TraitsTypes...> : public
std::conditional_t<IsTraitsOf<Class, TraitsType>::value, SelectTraits<Class, Index, TraitsType>, SelectTraits<Class, Index + 1, TraitsTypes...>>{};
template <typename Class, size_t Index, typename TraitsType>
......@@ -55,6 +59,30 @@ public:
}
};
template <typename Class, size_t Index>
struct SelectTraits<Class, Index> {
static constexpr bool valid = HasDefaultIOTraits<Class>::value;
private:
template <bool valid, typename = void>
struct _conditional{
using type = typename DefaultIOTraits<Class>::traitsType;
};
template <typename Dummy>
struct _conditional<false, Dummy>{
using type = void;
};
public:
using TypeTraits = typename _conditional< valid >::type;
template<typename ... Args>
static auto getTraitsInstance(const std::tuple<Args...>&) {
return DefaultIOTraits<Class>::getTraits();
}
};
struct PrintTraitedClass {
static int print(...){return 0;}
......
......@@ -7,116 +7,114 @@
#include <istream>
#include <map>
#include <sstream>
#include <GTMesh/Debug/Printers/PrintTraitedClass.h>
template <unsigned int MeshDimension, typename IndexType>
class VTKMeshDataReader {
static_assert (MeshDimension == 2 || MeshDimension == 3, "The VTK file format can represent data only in 2D or 3D");
/**
* @brief readColumn
* reads a single column of traited data
*/
static void readColumn(std::istream& ,...){
DBGMSG("capture");
throw std::runtime_error("capture of read column must not be called.");
}
template<typename T, unsigned int Index>
static auto readColumn(std::istream& ist, DataContainer<T, MeshDimension> &data,std::map<std::string, std::istream::pos_type>& dataPositions)
-> typename std::enable_if<
IsIndexable<typename DefaultIOTraits<T>::traitsType::template type<Index>>::value &&
MeshDimension == 3
>::type
template<typename T, unsigned int Index, typename ... TraitsArgs>
static
std::enable_if_t< IsIndexable<typename Traits<T, TraitsArgs...>::template type<Index>>::value &&
MeshDimension == 3 >
readColumn( std::istream& ist,
DataContainer<T, MeshDimension> &data,
std::map<std::string, std::istream::pos_type>& dataPositions,
const Traits<T, TraitsArgs...>& traits)
{
ist.seekg(dataPositions[DefaultIOTraits<T>::getTraits().template getName<Index>()]);
std::string line;
std::getline(ist, line);
ist.seekg(dataPositions[DefaultIOTraits<T>::getTraits().template getName<Index>()]);
ist.seekg(dataPositions[traits.template getName<Index>()]);
typename DefaultIOTraits<T>::traitsType::template type<Index> value;
typename Traits<T, TraitsArgs...>::template type<Index> value;
for (IndexType i = 0; i < data.size(); i++) {
for (unsigned int j = 0; j < DefaultIOTraits<T>::getTraits().template getValue<Index>(data.at(i)).size(); j++){
for (unsigned int j = 0; j < traits.template getValue<Index>(data.at(i)).size(); j++){
ist >> value[j];
}
DefaultIOTraits<T>::getTraits().template setValue<Index>(data.at(i), value);
traits.template setValue<Index>(data.at(i), value);
}
}
template<typename T, unsigned int Index>
static auto readColumn(std::istream& ist, DataContainer<T, MeshDimension> &data,std::map<std::string, std::istream::pos_type>& dataPositions)
template<typename T, unsigned int Index, typename ... TraitsArgs>
static auto readColumn( std::istream& ist,
DataContainer<T, MeshDimension> &data,
std::map<std::string, std::istream::pos_type>& dataPositions,
const Traits<T, TraitsArgs...>& traits)
-> typename std::enable_if<
IsIndexable<typename DefaultIOTraits<T>::traitsType::template type<Index>>::value &&
MeshDimension == 2
>::type
{
ist.seekg(dataPositions[DefaultIOTraits<T>::getTraits().template getName<Index>()]);
ist.seekg(dataPositions[traits.template getName<Index>()]);
typename DefaultIOTraits<T>::traitsType::template type<Index> value;
typename DefaultIOTraits<T>::traitsType::template type<Index> dummy;
typename Traits<T, TraitsArgs...>::template type<Index> value, dummy;
for (IndexType i = 0; i < data.size(); i++) {
for (unsigned int j = 0; j < DefaultIOTraits<T>::getTraits().template getValue<Index>(data.at(i)).size(); j++){
for (unsigned int j = 0; j < traits.template getValue<Index>(data.at(i)).size(); j++){
ist >> value[j];
}
ist >> dummy[0];
DefaultIOTraits<T>::getTraits().template setValue<Index>(data.at(i), value);
traits.template setValue<Index>(data.at(i), value);
}
}
template<typename T, unsigned int Index>
static auto readColumn(std::istream& ist, DataContainer<T, MeshDimension> &data,std::map<std::string, std::istream::pos_type>& dataPositions)
template<typename T, unsigned int Index, typename ... TraitsArgs>
static auto readColumn( std::istream& ist,
DataContainer<T, MeshDimension> &data,
std::map<std::string, std::istream::pos_type>& dataPositions,
const Traits<T, TraitsArgs...>& traits)
-> typename std::enable_if<
!IsIndexable<typename DefaultIOTraits<T>::traitsType::template type<Index>>::value
!IsIndexable<typename Traits<T, TraitsArgs...>::template type<Index>>::value
>::type
{
ist.seekg(dataPositions[DefaultIOTraits<T>::getTraits().template getName<Index>()]);
ist.seekg(dataPositions[traits.template getName<Index>()]);
typename DefaultIOTraits<T>::traitsType::template type<Index> value;
typename Traits<T, TraitsArgs...>::template type<Index> value;
for (IndexType i = 0; i < data.size(); i++){
ist >> value;
DefaultIOTraits<T>::getTraits().template setValue<Index>(data.at(i), value);
traits.template setValue<Index>(data.at(i), value);
}
}
private:
template<typename T,unsigned int Index = 0, typename Void = void>
struct readCellData{};
template<typename T,unsigned int Index>
struct readCellData <DefaultIOTraits<T>, Index, std::enable_if_t<Index < DefaultIOTraits<T>::size() - 1>>{
static void read(std::istream& ist, DataContainer<T, MeshDimension> &data, std::map<std::string, std::istream::pos_type>& dataPositions){
readColumn<T, Index>(ist, data, dataPositions);
readCellData<DefaultIOTraits<T>, Index + 1>::read(ist, data, dataPositions);
}
};
template<typename T,unsigned int Index>
struct readCellData <DefaultIOTraits<T>, Index, std::enable_if_t<Index == DefaultIOTraits<T>::size() - 1>>{
static void read(std::istream& ist, DataContainer<T, MeshDimension> &data, std::map<std::string, std::istream::pos_type>& dataPositions){
template< unsigned int Index,
typename T,
typename ... TraitsArgs,
std::enable_if_t<(Index < Traits<T, TraitsArgs...>::size()), bool> = true>
static void readData( std::istream& ist,
DataContainer<T, MeshDimension> &data,
std::map<std::string, std::istream::pos_type>& dataPositions,
const Traits<T, TraitsArgs...>& traits = DefaultIOTraits<T>::getTraits()){
//DBGVAR(IsIndexable<typename DefaultIOTraits<T>::traitsType::template type<Index>>::value);
readColumn<T, Index>(ist, data, dataPositions, traits);
readData< Index + 1 >(ist, data, dataPositions, traits);
}
readColumn<T, Index>(ist, data, dataPositions);
}
};
template< unsigned int Index,
typename T,
typename ... TraitsArgs,
std::enable_if_t<Index == Traits<T, TraitsArgs...>::size(), bool> = true>
static void readData( std::istream&,
DataContainer<T, MeshDimension> &,
std::map<std::string, std::istream::pos_type>&,
const Traits<T, TraitsArgs...>& = DefaultIOTraits<T>::getTraits()){}
......@@ -162,75 +160,94 @@ public:
std::map<std::string, std::istream::pos_type> dataPositions = indexData(ist);
readCellData<typename DefaultIOTraits<T>::traitsType>::read(ist, data, dataPositions);
readData(ist, data, dataPositions);
}
// Search for importable containers
private:
template<unsigned int Index, bool OK, typename T, unsigned int ...Dimensions>
static
typename std::enable_if<
MeshDataContainer<T, Dimensions...>::template dimensionAt<Index>() == MeshDimension &&
HasDefaultIOTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type>::value &&
(Index < sizeof... (Dimensions) - 1)
>::type
readMDC(std::istream& ist, MeshDataContainer<T, Dimensions...> &data, std::map<std::string, std::istream::pos_type>& dataPositions){
template <unsigned int Index, bool OK = false>
struct MeshDataIterator{
template<typename T, unsigned int ...Dimensions, typename ... TraitsTuple>
static
typename std::enable_if<
(!SelectTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type, 0, TraitsTuple...>::valid)
>::type
readFromStream( std::istream& ist,
MeshDataContainer<T, Dimensions...> &data,
std::map<std::string, std::istream::pos_type>& dataPositions,
const std::tuple<TraitsTuple...>& tupTraits )
{
MeshDataIterator<Index - 1, OK>::readFromStream(ist, data, dataPositions, tupTraits);
}
using type = typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type;
readCellData<
DefaultIOTraits<type>
>::read(ist, data.template getDataByPos<Index>(), dataPositions);
readMDC<Index + 1, true, T, Dimensions...>(ist, data, dataPositions);
template<typename T, unsigned int ...Dimensions, typename ... TraitsTuple>
static
typename std::enable_if<
(SelectTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type, 0, TraitsTuple...>::valid)
>::type
readFromStream( std::istream& ist,
MeshDataContainer<T, Dimensions...> &data,
std::map<std::string, std::istream::pos_type>& dataPositions,
const std::tuple<TraitsTuple...>& tupTraits )
{
using type = typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type;
MeshDataIterator<Index - 1, true>:: writeToStream(ist, data, dataPositions, tupTraits);
readData<0>(ist, data.template getDataByPos<Index>(), dataPositions, SelectTraits<type, 0, TraitsTuple...>::getTraitsInstance(tupTraits));
}
};
}
template <bool OK>
struct MeshDataIterator <0, OK> {
template<typename T, unsigned int ...Dimensions, typename ... TraitsTuple>
static
typename std::enable_if<
(!SelectTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<0>::type, 0, TraitsTuple...>::valid)
>::type
readFromStream( std::istream&,
MeshDataContainer<T, Dimensions...>&,
std::map<std::string, std::istream::pos_type>&,
const std::tuple<TraitsTuple...>& )
{
static_assert (OK , "The mesh data container must have at least one DataContainer mapped to cells with traits for example using macro MAKE_ATTRIBUTE_TRAIT see header Traits.h");
template<unsigned int Index, bool OK, typename T, unsigned int ...Dimensions>
static
typename std::enable_if<
(MeshDataContainer<T, Dimensions...>::template dimensionAt<Index>() != MeshDimension ||
!HasDefaultIOTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type>::value) &&
(Index < sizeof... (Dimensions) - 1)
>::type
readMDC(std::istream& ist, MeshDataContainer<T, Dimensions...> &data, std::map<std::string, std::istream::pos_type>& dataPositions){
}
readMDC<Index + 1, OK, T, Dimensions...>(ist, data, dataPositions);
template<typename T, unsigned int ...Dimensions, typename ... TraitsTuple>
static
typename std::enable_if<
(SelectTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<0>::type, 0, TraitsTuple...>::valid)
>::type
readFromStream( std::istream& ist,
MeshDataContainer<T, Dimensions...>& data,
std::map<std::string, std::istream::pos_type>& dataPositions,
const std::tuple<TraitsTuple...>& tupTraits)
{
using type = typename MeshDataContainer<T, Dimensions...>::template DataContainerType<0>::type;
}
readData<0>(ist, data.template getDataByPos<0>(), dataPositions, SelectTraits<type, 0, TraitsTuple...>::getTraitsInstance(tupTraits));
template<unsigned int Index, bool OK, typename T, unsigned int ...Dimensions>
static
typename std::enable_if<
MeshDataContainer<T, Dimensions...>::template dimensionAt<Index>() == MeshDimension &&
HasDefaultIOTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type>::value &&
(Index == sizeof... (Dimensions) - 1)
>::type
readMDC(std::istream& ist, MeshDataContainer<T, Dimensions...> &data, std::map<std::string, std::istream::pos_type>& dataPositions){
using type = typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type;
readCellData<
DefaultIOTraits<type>
>::read(ist, data.template getDataByPos<Index>(), dataPositions);
}
}
};
template<unsigned int Index, bool OK, typename T, unsigned int ...Dimensions>
static
typename std::enable_if<
(MeshDataContainer<T, Dimensions...>::template dimensionAt<Index>() != MeshDimension ||
!HasDefaultIOTraits<typename MeshDataContainer<T, Dimensions...>::template DataContainerType<Index>::type>::value) &&
(Index == sizeof... (Dimensions) - 1)
>::type
readMDC(std::istream& , MeshDataContainer<T, Dimensions...> &, std::map<std::string, std::istream::pos_type>& ){
public:
template<typename T, unsigned int ...Dimensions, typename ... TraitsTypes>
static void readFromStream( std::istream& ist,
MeshDataContainer<T, Dimensions...>& data,
const std::tuple<TraitsTypes...>& tupTraits = std::tuple<>()) {
static_assert (OK, "The passed MeshDataContainer must have at least one DataContainer mapped to cells and data with DefaultIOTraits defined!");
std::map<std::string, std::istream::pos_type> dataPositions = indexData(ist);
MeshDataIterator<sizeof... (Dimensions) - 1>::readFromStream(ist, data, dataPositions, tupTraits);
}
public:
template<typename T, unsigned int ...Dimensions>
static void readFromStream(std::istream& ist, MeshDataContainer<T, Dimensions...>& data) {
template<typename T, unsigned int ...Dimensions, typename ... TraitsTypes>
static void readFromStream( std::istream& ist,
const TraitsBinder<MeshDataContainer<T, Dimensions...>, TraitsTypes...>& data) {
std::map<std::string, std::istream::pos_type> dataPositions = indexData(ist);
readMDC<0, false>(ist, data, dataPositions);
MeshDataIterator<sizeof... (Dimensions) - 1>::readFromStream(ist, data.object, dataPositions, data.tupTraits);
}
};
......
// Test of the UnstructuredMesh class
#ifdef HAVE_GTEST
#include <gtest/gtest.h>
// #else
// #define TEST(_1,_2) void _1()
// #define EXPECT_TRUE(_1) if(!_1)DBGVAR(_1);(void)(_1)
// #define EXPECT_FALSE(_1) DBGCHECK;(void)(_1)
// #define EXPECT_EQ(_1,_2) if (!(_1 == _2))DBGVAR(_1,_2);(void)(_1 == _2)
// #define EXPECT_ANY_THROW(_1) DBGCHECK;try{(_1);}catch(...){}
// #endif
#include "GTMesh/Debug/Debug.h"
#include <list>
#include <map>
......
Supports Markdown
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