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

Template test out of line specialization

orderedConnections...
parent 4f757196
Loading
Loading
Loading
Loading
+75 −1
Original line number Diff line number Diff line
@@ -171,6 +171,74 @@ struct is_indexable<
        > : public integral_constant<bool, false>{};


template <typename T>
class OutOfLineSpecialization {
public:
    template<typename ... Sequence>
    static void printSeq(Sequence...);

    template<T... data>
    static void onlySpec();
};

template<typename T> template<typename...Sequence>
void OutOfLineSpecialization<T>::printSeq(Sequence... onlyOne) {
    DBGMSG("capture");
    DBGVAR(onlyOne...);
}
template<> template<typename...Sequence>
void OutOfLineSpecialization<int>::printSeq(Sequence... onlyOne) {
    DBGMSG("int");
    DBGVAR(onlyOne...);
}


template<> template<int...data>
void OutOfLineSpecialization<int>::onlySpec() {
    DBGMSG("int");
    DBGVAR(data...);
}



template <typename T>
class InLineSpecialization {
public:
    template<typename...Sequence>
    static void printSeq(Sequence... onlyOne) {
        DBGMSG("capture");
        DBGVAR(onlyOne...);
    }
};


template <>
class InLineSpecialization<int> {
public:
    template<typename...Sequence>
    static void printSeq(Sequence... onlyOne) {
        DBGMSG("int");
        DBGVAR(onlyOne...);
    }
    template<int...data>
    static void onlySpec() {
        DBGMSG("int");
        DBGVAR(data...);
    }
};


template<typename T>
void callSpec() {
    // supr, tohle nabízí
    OutOfLineSpecialization<T>::printSeq(1);
    OutOfLineSpecialization<T>::template onlySpec<2>();

    InLineSpecialization<T>::printSeq(1);
    InLineSpecialization<T>::template onlySpec<3>();
}


int main()
{

@@ -195,6 +263,12 @@ int main()
    //DBGVAR(is_same<decltype(&vector<double>::operator[]), typename member_const_function_ptr<vector<double>,const double&, size_t>::type>::value);

    DBGVAR(is_indexable<const vector<double>>::value);
    cout << "Hello World!" << endl;


    OutOfLineSpecialization<size_t>::printSeq(1);
    OutOfLineSpecialization<int>::printSeq(1);

    callSpec<int>();

    return 0;
}
+41 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include "Vector.h"
#include <valarray>
#include <set>
#include <map>

template <typename Type, Type startIndex, Type EndIndex, int increment = 1, Type... t>
struct MakeCustomIntegerSequence : public MakeCustomIntegerSequence<Type, startIndex + increment, EndIndex, increment, t..., startIndex> {
@@ -545,6 +546,14 @@ struct MeshApply {

template<unsigned int StartDim, unsigned int TargetDim>
struct MeshConnections {
    /**
     * @brief connections<HR>
     * Detects connections of mesh elements of StartDim to TargetDim.
     * Returns a MeshDataContainer of set<IndexType> allocated to StartDim elements.
     * The indexes are ordered in ascending way.
     * @param mesh
     * @return
     */
    template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve>
    static MeshDataContainer<std::set<IndexType>, StartDim> connections(
            MeshElements<MeshDimension, IndexType, Real, Reserve...>& mesh
@@ -556,6 +565,38 @@ struct MeshConnections {

        return result;
    }

    /**
     * @brief orderedConnections<HR>
     * This function returns connection in original sequence as in the mesh.
     * @param mesh
     * @return
     */
    template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve>
    static MeshDataContainer<std::vector<IndexType>, StartDim> orderedConnections(
            MeshElements<MeshDimension, IndexType, Real, Reserve...>& mesh
            ) {
        MeshDataContainer<std::map<IndexType, IndexType>, StartDim> tempMap(mesh);

        MeshApply<StartDim, TargetDim, MeshDimension>::apply(mesh, [&tempMap](IndexType ori, IndexType element){
            IndexType size = tempMap.template getDataByPos<0>().at(ori).size();
            tempMap.template getDataByPos<0>().at(ori).insert({element, size});
        });

        MeshDataContainer<std::set<IndexType>, StartDim> result(mesh);
        for (IndexType i = 0; i < mesh.template getElements<StartDim>().size(); i++){
            //resize the vector at the position
            result.template getDataByPos<0>().at(i).resize(
                tempMap.template getDataByPos<0>().at(i).size()
            );

            for(std::pair<IndexType, IndexType>& mapElem : tempMap) {
                result.template getDataByPos<0>().at(i).at(mapElem.second) = mapElem.first;
            }
        }
        return result;
    }

};

template<unsigned int FromDim, unsigned int ToDim, bool Descend = true>
+1 −1
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.10.0, 2019-10-13T13:53:45. -->
<!-- Written by QtCreator 4.10.0, 2019-10-14T11:17:53. -->
<qtcreator>
 <data>
  <variable>EnvironmentId</variable>
+32 −16
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ public:
     * @brief lastHash<HR>
     * The hash of the last written mesh.
     */
    size_t lastHash;
    size_t lastHash = 0;
    /**
     * @brief cellVert<HR>
     * Vertices of all cells in correct order for vtk export.
@@ -220,7 +220,8 @@ public:

    /**
     * @brief indexFace<HR>
     * This funcion stores indexes of vertices in correct order
     * This funcion return indexes of vertices of a face in correct order
     * with respect to edge orientation
     * in output vector verticesIndexed
     * @param mesh the structure of the mesh
     * @param face the face of the mesh to be indexed
@@ -269,16 +270,23 @@ public:

    }




    /**
     * @brief indexMesh<HR>
     * This function creates vector of indexes of vertices for each cell in order suitable
     * for VTK output. Moreover in case of elements type different from
     * any VTK cell type, the cell is split into tetrahedrons. The tetrahedrons are
     * made for each edge of every faces. The tetrahedrons is made of both edges vertices
     * and cell and face center.
     * @param mesh Mesh to be indexed
     * @param cellTypes Vector of known cell types. If a cell type is not known then a method
     * of splitting into tetrahedrons is used.
     */
    template<unsigned int ...Reserve>
    void indexMesh(MeshElements<3, IndexType, Real, Reserve...>& mesh,
                   MeshDataContainer<typename writer::type::ElementType, 3> cellTypes){
        size_t curHash = writer::computeHash(mesh);

        // if the mesh is the same as it was, return
        if (lastHash == curHash){
            return;
        }
        lastHash = curHash;

        appendedVertices.clear();
        cellVert.template getDataByPos<0>().clear();
@@ -288,8 +296,7 @@ DBGMSG("indexing mesh");
        // write cells of the mesh
        // prepare connections
        auto cellVert = MeshConnections<3,0>::connections(mesh);
        auto cellFace = MeshConnections<3,2>::connections(mesh);
        auto faceVert = MeshConnections<2,0>::connections(mesh);

        // prepare orientation for correct export
        // this is very expensive procedure
        auto faceEdgeOri = edgesOrientation(mesh);
@@ -331,8 +338,8 @@ DBGMSG("indexing mesh");
                // write vertices of one face
                typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr;
                // search for the base face
                for (IndexType faceIndex : cellFace[cell]){
                    if (faceVert.template getDataByPos<0>().at(faceIndex).size() > 3){
                for (IndexType faceIndex : mesh.template getElement<3>(cell.getIndex()).getSubelements()){
                    if (mesh.template getElements<2>().at(faceIndex).getSubelements().getNumberOfSubElements() > 3){
                        face = &mesh.getFaces().at(faceIndex);
                    }
                }
@@ -360,11 +367,12 @@ DBGMSG("indexing mesh");
                // search for the base face

                for (IndexType faceIndex : mesh.template getElement<3>(cell.getIndex()).getSubelements()){
                    if (faceVert.template getDataByPos<0>().at(faceIndex).size() == 3){
                    if (mesh.template getElements<2>().at(faceIndex).getSubelements().getNumberOfSubElements() == 3){
                        face = &mesh.getFaces().at(faceIndex);
                        break;
                    }
                }

                indexFace(mesh, *face, cell, faceEdgeOri, vertWrit);
                // write vertices of the oposite triangular side

@@ -518,8 +526,16 @@ DBGMSG("indexing mesh");
    void writeToStream(std::ostream& ost,
                       MeshElements<3, IndexType, Real, Reserve...>& mesh,
                       MeshDataContainer<typename writer::type::ElementType, 3> cellTypes){
        // create index of mesh
        // create index of mesh if the mesh has changed
        size_t curHash = writer::computeHash(mesh);

        // if the mesh is not the same as it was,
        // then update the index
        if (lastHash != curHash){
            indexMesh(mesh, cellTypes);
        }
        lastHash = curHash;

        // first write verices
        ost << "POINTS " << mesh.getVertices().size() + appendedVertices.size() <<
               " double" << std::endl;