Skip to content
Snippets Groups Projects
Verified Commit 76de79f1 authored by Sébastien Villemot's avatar Sébastien Villemot
Browse files

k-order DLL: simplify workaround for a GCC bug using C++20 features

parent 0213b140
No related branches found
No related tags found
No related merge requests found
/*
* Copyright © 2004 Ondra Kamenik
* Copyright © 2019 Dynare Team
* Copyright © 2019-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -19,39 +19,6 @@
*/
#include "t_polynomial.hh"
#include "kron_prod.hh"
// PowerProvider::getNext() unfolded code
/* This method constructs unfolded ‘ut’ of higher dimension, deleting
the previous. */
const URSingleTensor&
PowerProvider::getNext(dummy<URSingleTensor>)
{
if (ut)
{
auto ut_new = std::make_unique<URSingleTensor>(nv, ut->dimen() + 1);
KronProd::kronMult(ConstVector(origv), ConstVector(ut->getData()), ut_new->getData());
ut = std::move(ut_new);
}
else
{
ut = std::make_unique<URSingleTensor>(nv, 1);
ut->getData() = origv;
}
return *ut;
}
// PowerProvider::getNext() folded code
/* This method just constructs next unfolded ‘ut’ and creates folded ‘ft’. */
const FRSingleTensor&
PowerProvider::getNext(dummy<FRSingleTensor>)
{
getNext<URSingleTensor>();
ft = std::make_unique<FRSingleTensor>(*ut);
return *ft;
}
UTensorPolynomial::UTensorPolynomial(const FTensorPolynomial& fp) :
TensorPolynomial<UFSTensor, UGSTensor, URSingleTensor>(fp.nrows(), fp.nvars())
......
/*
* Copyright © 2004 Ondra Kamenik
* Copyright © 2019-2023 Dynare Team
* Copyright © 2019-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -55,6 +55,7 @@
#define T_POLYNOMIAL_HH
#include "fs_tensor.hh"
#include "kron_prod.hh"
#include "pascal_triangle.hh"
#include "rfs_tensor.hh"
#include "t_container.hh"
......@@ -89,33 +90,48 @@ public:
{
}
/*
We need to select getNext() implementation at compile type depending on a
type parameter.
template<class T>
const T& getNext();
Unfortunately full specialization is not possible at class scope. This may
be a bug in GCC 6. See:
https://stackoverflow.com/questions/49707184/explicit-specialization-in-non-namespace-scope-does-not-compile-in-gcc
// PowerProvider::getNext() unfolded code
/* This method constructs unfolded ‘ut’ of higher dimension, deleting
the previous.
Apply the workaround suggested in:
https://stackoverflow.com/questions/3052579/explicit-specialization-in-non-namespace-scope
*/
template<typename T>
struct dummy
Ideally we would like to use a full-specialization of the template, but this is not
possible due to a GCC bug, so we use a workaround using std::same_as concept.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282 */
template<std::same_as<URSingleTensor> T>
const T&
getNext()
{
using type = T;
};
if (ut)
{
auto ut_new = std::make_unique<URSingleTensor>(nv, ut->dimen() + 1);
KronProd::kronMult(ConstVector(origv), ConstVector(ut->getData()), ut_new->getData());
ut = std::move(ut_new);
}
else
{
ut = std::make_unique<URSingleTensor>(nv, 1);
ut->getData() = origv;
}
return *ut;
}
template<class T>
// PowerProvider::getNext() folded code
/* This method just constructs next unfolded ‘ut’ and creates folded ‘ft’.
Ideally we would like to use a full-specialization of the template, but this is not
possible due to a GCC bug, so we use a workaround using std::same_as concept.
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282 */
template<std::same_as<FRSingleTensor> T>
const T&
getNext()
{
return getNext(dummy<T>());
getNext<URSingleTensor>();
ft = std::make_unique<FRSingleTensor>(*ut);
return *ft;
}
private:
const URSingleTensor& getNext(dummy<URSingleTensor>);
const FRSingleTensor& getNext(dummy<FRSingleTensor>);
};
/* The tensor polynomial is basically a tensor container which is more
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment