Commit 7f00308f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

functor-degree wrapper corrected

parent fd417732
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
* Web: https://fusionforge.zih.tu-dresden.de/projects/amdis * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
* *
* Authors: * Authors:
* Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
* *
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* This file is part of AMDiS * This file is part of AMDiS
* *
* See also license.opensource.txt in the distribution. * See also license.opensource.txt in the distribution.
* *
******************************************************************************/ ******************************************************************************/
...@@ -34,10 +34,10 @@ ...@@ -34,10 +34,10 @@
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
#include <functional> #include <functional>
namespace AMDiS namespace AMDiS
{ {
/// for_each for std::tuple /// for_each for std::tuple
template<std::size_t I = 0, typename FuncT, typename... Tp> template<std::size_t I = 0, typename FuncT, typename... Tp>
...@@ -54,8 +54,8 @@ namespace AMDiS ...@@ -54,8 +54,8 @@ namespace AMDiS
template<int I> template<int I>
using int_ = std::integral_constant<int, I>; using int_ = std::integral_constant<int, I>;
namespace traits namespace traits
{ {
/// get the degree of a functor by combining the degrees of the arguments /// get the degree of a functor by combining the degrees of the arguments
...@@ -65,14 +65,14 @@ namespace AMDiS ...@@ -65,14 +65,14 @@ namespace AMDiS
template<typename... Int> template<typename... Int>
static int eval(F f, Int... d) { return 0; } static int eval(F f, Int... d) { return 0; }
}; };
template<typename F> template<typename F>
struct functor_degree<F, typename enable_if< boost::is_base_of<FunctorBase, F> >::type > struct functor_degree<F, typename enable_if< boost::is_base_of<FunctorBase, F> >::type >
{ {
template<typename... Int> template<typename... Int>
static int eval(F f, Int... d) { return f.getDegree(d...); } static int eval(F f, Int... d) { return f.getDegree(d...); }
}; };
// specialization for abstract-functions // specialization for abstract-functions
template<typename R, typename... Args> template<typename R, typename... Args>
struct functor_degree<AbstractFunction<R, Args...> > struct functor_degree<AbstractFunction<R, Args...> >
...@@ -80,28 +80,28 @@ namespace AMDiS ...@@ -80,28 +80,28 @@ namespace AMDiS
template<typename... Int> template<typename... Int>
static int eval(AbstractFunction<R, Args...> const& fct, Int... d) { return fct.getDegree(); } static int eval(AbstractFunction<R, Args...> const& fct, Int... d) { return fct.getDegree(); }
}; };
template<typename R, typename Arg0, typename Arg1> template<typename R, typename Arg0, typename Arg1>
struct functor_degree<BinaryAbstractFunction<R, Arg0, Arg1> > struct functor_degree<BinaryAbstractFunction<R, Arg0, Arg1> >
{ {
template<typename... Int> template<typename... Int>
static int eval(BinaryAbstractFunction<R, Arg0, Arg1> const& fct, Int... d) { return fct.getDegree(); } static int eval(BinaryAbstractFunction<R, Arg0, Arg1> const& fct, Int... d) { return fct.getDegree(); }
}; };
template<typename R, typename Arg0, typename Arg1, typename Arg2> template<typename R, typename Arg0, typename Arg1, typename Arg2>
struct functor_degree<TertiaryAbstractFunction<R, Arg0, Arg1, Arg2> > struct functor_degree<TertiaryAbstractFunction<R, Arg0, Arg1, Arg2> >
{ {
template<typename... Int> template<typename... Int>
static int eval(TertiaryAbstractFunction<R, Arg0, Arg1, Arg2> const& fct, Int... d) { return fct.getDegree(); } static int eval(TertiaryAbstractFunction<R, Arg0, Arg1, Arg2> const& fct, Int... d) { return fct.getDegree(); }
}; };
} // end namespace traits } // end namespace traits
namespace result_of namespace result_of
{ {
template<class T> template<class T>
struct void_{ typedef void type; }; struct void_{ typedef void type; };
/// extract result type from function pointers /// extract result type from function pointers
template <class FPtr> template <class FPtr>
struct Function; struct Function;
...@@ -117,7 +117,7 @@ namespace AMDiS ...@@ -117,7 +117,7 @@ namespace AMDiS
{ {
typedef R type; typedef R type;
}; };
template <class T> template <class T>
typename Function<T>::type function_helper(T); typename Function<T>::type function_helper(T);
...@@ -127,7 +127,7 @@ namespace AMDiS ...@@ -127,7 +127,7 @@ namespace AMDiS
{ {
typedef decltype(function_helper(&F::operator())) type; typedef decltype(function_helper(&F::operator())) type;
}; };
template <class R, class... As> template <class R, class... As>
struct Functor<std::function<R(As...)> > struct Functor<std::function<R(As...)> >
{ {
...@@ -139,50 +139,50 @@ namespace AMDiS ...@@ -139,50 +139,50 @@ namespace AMDiS
{ {
typedef typename F::value_type type; typedef typename F::value_type type;
}; };
template <class F> template <class F>
struct Functor<F, typename void_<typename F::result_type>::type> struct Functor<F, typename void_<typename F::result_type>::type>
{ {
typedef typename F::result_type type; typedef typename F::result_type type;
}; };
} // end namespace result_of } // end namespace result_of
namespace detail
namespace detail
{ {
/// Functor that initializes the feSpace list /// Functor that initializes the feSpace list
template<typename List> template<typename List>
struct InsertFeSpaces struct InsertFeSpaces
{ {
List& feSpaces; List& feSpaces;
InsertFeSpaces(List& feSpaces_) : feSpaces(feSpaces_) {}; InsertFeSpaces(List& feSpaces_) : feSpaces(feSpaces_) {};
template<typename Term> template<typename Term>
void operator()(Term& term) { void operator()(Term& term) {
term.insertFeSpaces(feSpaces); term.insertFeSpaces(feSpaces);
} }
}; };
/// Functor that is called on each term to initialize it on an element /// Functor that is called on each term to initialize it on an element
template<typename OT> template<typename OT>
struct InitElement struct InitElement
{ {
OT* ot; OT* ot;
const ElInfo *elInfo, *elInfo2; const ElInfo *elInfo, *elInfo2;
SubAssembler* subAssembler; SubAssembler* subAssembler;
Quadrature *quad; Quadrature *quad;
const BasisFunction *basisFct; const BasisFunction *basisFct;
InitElement(OT* ot_, const ElInfo* elInfo_, SubAssembler* subAssembler_, Quadrature *quad_, const BasisFunction *basisFct_) InitElement(OT* ot_, const ElInfo* elInfo_, SubAssembler* subAssembler_, Quadrature *quad_, const BasisFunction *basisFct_)
: ot(ot_), elInfo(elInfo_), elInfo2(NULL), subAssembler(subAssembler_), : ot(ot_), elInfo(elInfo_), elInfo2(NULL), subAssembler(subAssembler_),
quad(quad_), basisFct(basisFct_) {} quad(quad_), basisFct(basisFct_) {}
InitElement(OT* ot_, const ElInfo* smallElInfo_, const ElInfo* largeElInfo_, SubAssembler* subAssembler_, Quadrature *quad_, const BasisFunction *basisFct_) InitElement(OT* ot_, const ElInfo* smallElInfo_, const ElInfo* largeElInfo_, SubAssembler* subAssembler_, Quadrature *quad_, const BasisFunction *basisFct_)
: ot(ot_), elInfo(smallElInfo_), elInfo2(largeElInfo_), subAssembler(subAssembler_), : ot(ot_), elInfo(smallElInfo_), elInfo2(largeElInfo_), subAssembler(subAssembler_),
quad(quad_), basisFct(basisFct_) {} quad(quad_), basisFct(basisFct_) {}
template<typename Term> template<typename Term>
void operator()(Term& term) { void operator()(Term& term) {
if (elInfo2) if (elInfo2)
...@@ -191,21 +191,21 @@ namespace AMDiS ...@@ -191,21 +191,21 @@ namespace AMDiS
term.initElement(ot, elInfo, subAssembler, quad, basisFct); term.initElement(ot, elInfo, subAssembler, quad, basisFct);
} }
}; };
} // end namespace detail } // end namespace detail
/// Operator term with arbitrary number of sub-term (expressions) /// Operator term with arbitrary number of sub-term (expressions)
template <class... Terms> template <class... Terms>
struct LazyOperatorTerms : public LazyOperatorTermBase struct LazyOperatorTerms : public LazyOperatorTermBase
{ {
std::tuple<Terms...> term_tuple; std::tuple<Terms...> term_tuple;
template <class... Terms_> template <class... Terms_>
LazyOperatorTerms(Terms_... terms_) LazyOperatorTerms(Terms_... terms_)
: term_tuple(terms_...) : term_tuple(terms_...)
{ } { }
template <class List> template <class List>
inline void insertFeSpaces(List& feSpaces) inline void insertFeSpaces(List& feSpaces)
{ {
...@@ -214,7 +214,7 @@ namespace AMDiS ...@@ -214,7 +214,7 @@ namespace AMDiS
template <class OT> template <class OT>
inline void initElement(OT* ot, const ElInfo* elInfo, inline void initElement(OT* ot, const ElInfo* elInfo,
SubAssembler* subAssembler, Quadrature *quad, SubAssembler* subAssembler, Quadrature *quad,
const BasisFunction *basisFct = NULL) const BasisFunction *basisFct = NULL)
{ {
for_each(term_tuple, detail::InitElement<OT>(ot, elInfo, subAssembler, quad, basisFct)); for_each(term_tuple, detail::InitElement<OT>(ot, elInfo, subAssembler, quad, basisFct));
...@@ -222,20 +222,20 @@ namespace AMDiS ...@@ -222,20 +222,20 @@ namespace AMDiS
template <class OT> template <class OT>
inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo,
SubAssembler* subAssembler, Quadrature *quad, SubAssembler* subAssembler, Quadrature *quad,
const BasisFunction *basisFct = NULL) const BasisFunction *basisFct = NULL)
{ {
for_each(term_tuple, detail::InitElement<OT>(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct)); for_each(term_tuple, detail::InitElement<OT>(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct));
} }
inline double operator()(const int& iq) const; inline double operator()(const int& iq) const;
}; };
// the expressions // the expressions
// _____________________________________________________________________________ // _____________________________________________________________________________
namespace expressions namespace expressions
{ {
/// Functor that takes arbitrary number of arguments /// Functor that takes arbitrary number of arguments
template <class F, class... Terms> template <class F, class... Terms>
...@@ -243,29 +243,29 @@ namespace AMDiS ...@@ -243,29 +243,29 @@ namespace AMDiS
{ {
typedef LazyOperatorTerms<Terms...> super; typedef LazyOperatorTerms<Terms...> super;
static const int N = sizeof...(Terms); static const int N = sizeof...(Terms);
typedef typename result_of::Functor<F>::type value_type; typedef typename result_of::Functor<F>::type value_type;
BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: You have to define a result_type for your Functor **********" ); BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: You have to define a result_type for your Functor **********" );
F f; ///< the functor F f; ///< the functor
template <class... Terms_> template <class... Terms_>
FunctionN(F const& f_, Terms_... terms_) FunctionN(F const& f_, Terms_... terms_)
: super(terms_...), f(f_) {} : super(terms_...), f(f_) {}
// call f.getDegree() function // call f.getDegree() function
template<int I, class... Terms_> template<int I, class... Terms_>
int getDegree(int_<I>, Terms_&&... terms) const int getDegree(int_<I>, Terms_&&... terms) const
{ {
return getDegree(int_<I-1>(), std::get<I-1>(super::term_tuple), std::forward<Terms_>(terms)...); return getDegree(int_<I-1>(), std::get<I-1>(super::term_tuple), std::forward<Terms_>(terms)...);
} }
template <class... Terms_> template <class... Terms_>
int getDegree(int_<0>, Terms_&&... terms) const int getDegree(int_<0>, Terms_&&... terms) const
{ {
return traits::functor_degree<F>::eval(f, terms.getDegree()...); return traits::functor_degree<F>::eval(f, terms.getDegree()...);
} }
int getDegree() const int getDegree() const
{ {
return getDegree(int_<N>()); return getDegree(int_<N>());
...@@ -277,42 +277,42 @@ namespace AMDiS ...@@ -277,42 +277,42 @@ namespace AMDiS
{ {
return eval(iq, int_<I-1>(), std::get<I-1>(super::term_tuple), std::forward<Terms_>(terms)...); return eval(iq, int_<I-1>(), std::get<I-1>(super::term_tuple), std::forward<Terms_>(terms)...);
} }
template <class... Terms_> template <class... Terms_>
inline value_type eval(const int& iq, int_<0>, Terms_&&... terms) const inline value_type eval(const int& iq, int_<0>, Terms_&&... terms) const
{ {
return f(terms(iq)...); // f(term1(iq), term2(iq), term3(iq),...) return f(terms(iq)...); // f(term1(iq), term2(iq), term3(iq),...)
} }
inline value_type operator()(const int& iq) const { return eval(iq, int_<N>()); } inline value_type operator()(const int& iq) const { return eval(iq, int_<N>()); }
template <int I> template <int I>
std::string str(int_<I>) const std::string str(int_<I>) const
{ {
return str(int_<I-1>()) + ", " + std::get<I>(super::term_tuple).str(); return str(int_<I-1>()) + ", " + std::get<I>(super::term_tuple).str();
} }
std::string str(int_<0>) const std::string str(int_<0>) const
{ {
return std::get<0>(super::term_tuple).str(); return std::get<0>(super::term_tuple).str();
} }
std::string str() const { return std::string("F(") + str(int_<N-1>()) + ")"; } std::string str() const { return std::string("F(") + str(int_<N-1>()) + ")"; }
}; };
template<typename F, typename Term> template<typename F, typename Term>
using Function1 = FunctionN<F, Term>; using Function1 = FunctionN<F, Term>;
template<typename F, typename Term1, typename Term2> template<typename F, typename Term1, typename Term2>
using Function2 = FunctionN<F, Term1, Term2>; using Function2 = FunctionN<F, Term1, Term2>;
template<typename F, typename Term1, typename Term2, typename Term3> template<typename F, typename Term1, typename Term2, typename Term3>
using Function3 = FunctionN<F, Term1, Term2, Term3>; using Function3 = FunctionN<F, Term1, Term2, Term3>;
template<typename F, typename Term1, typename Term2, typename Term3, typename Term4> template<typename F, typename Term1, typename Term2, typename Term3, typename Term4>
using Function4 = FunctionN<F, Term1, Term2, Term3, Term4>; using Function4 = FunctionN<F, Term1, Term2, Term3, Term4>;
/// A wrapper functor for AMDiS::AbstractFunctions /// A wrapper functor for AMDiS::AbstractFunctions
template <class TOut, class TIn> template <class TOut, class TIn>
struct Wrapper : public FunctorBase struct Wrapper : public FunctorBase
...@@ -320,63 +320,63 @@ namespace AMDiS ...@@ -320,63 +320,63 @@ namespace AMDiS
typedef TOut result_type; typedef TOut result_type;
Wrapper(AbstractFunction<TOut, TIn>* fct_) : fct(fct_) {} Wrapper(AbstractFunction<TOut, TIn>* fct_) : fct(fct_) {}
int getDegree(int degree) const { return fct->getDegree(); } int getDegree(int degree) const { return fct->getDegree(); }
TOut operator()(const TIn& x) const TOut operator()(const TIn& x) const
{ {
return (*fct)(x); return (*fct)(x);
} }
protected: protected:
AbstractFunction<TOut, TIn>* fct; AbstractFunction<TOut, TIn>* fct;
}; };
template <int D, class F> template <int D, class F>
struct DegreeWrapper : public FunctorBase struct DegreeWrapper : public FunctorBase
{ {
typedef typename result_of::Functor<F>::type result_type; typedef typename result_of::Functor<F>::type result_type;
DegreeWrapper(F&& fct_) : fct(fct_) {} DegreeWrapper(F const& fct_) : fct(fct_) {}
template <class... Int> template <class... Int>
int getDegree(Int... degrees) const { return D; } int getDegree(Int... degrees) const { return D; }
template <class... Ts> template <class... Ts>
result_type operator()(Ts&&... args) const result_type operator()(Ts&&... args) const
{ {
return fct(args...); return fct(std::forward<Ts>(args)...);
} }
protected: protected:
F fct; F fct;
}; };
template <class F, class DegF> template <class F, class DegF>
struct DegreeWrapper2 : public FunctorBase struct DegreeWrapper2 : public FunctorBase
{ {
typedef typename result_of::Functor<F>::type result_type; typedef typename result_of::Functor<F>::type result_type;
DegreeWrapper2(F&& fct_, DegF&& degfct_) DegreeWrapper2(F const& fct_, DegF const& degfct_)
: fct(fct_), degfct(degfct_) {} : fct(fct_), degfct(degfct_) {}
template <class... Int> template <class... Int>
int getDegree(Int... degrees) const int getDegree(Int... degrees) const
{ {
return degfct(degrees...); return degfct(degrees...);
} }
template <class... Ts> template <class... Ts>
result_type operator()(Ts&&... args) const result_type operator()(Ts&&... args) const
{ {
return fct(args...); return fct(std::forward<Ts>(args)...);
} }
protected: protected:
F fct; F fct;
DegF degfct; DegF degfct;
}; };
} // end namespace expressions } // end namespace expressions
...@@ -387,16 +387,16 @@ namespace AMDiS ...@@ -387,16 +387,16 @@ namespace AMDiS
struct FunctionN : std::enable_if struct FunctionN : std::enable_if
< <
and_< typename traits::is_valid_arg<Terms>::type... >::value, and_< typename traits::is_valid_arg<Terms>::type... >::value,
expressions::FunctionN< F, typename traits::to_expr<Terms>::type...> expressions::FunctionN< F, typename traits::to_expr<Terms>::type...>
> {}; > {};
template <typename F, typename Term> template <typename F, typename Term>