mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-09-12 17:33:15 +08:00
Exploit fixed values in seq and reverse with C++98 compatibility
This commit is contained in:
parent
7691723e34
commit
54f3fbee24
@ -28,30 +28,31 @@ template<int N> struct aseq_negate<fix_t<N> > {
|
|||||||
// Compilation error in the following case:
|
// Compilation error in the following case:
|
||||||
template<> struct aseq_negate<fix_t<DynamicIndex> > {};
|
template<> struct aseq_negate<fix_t<DynamicIndex> > {};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,
|
template<typename FirstType,typename SizeType,typename IncrType,
|
||||||
bool FirstIsSymbolic=Symbolic::is_symbolic<FirstType>::value,
|
bool FirstIsSymbolic=Symbolic::is_symbolic<FirstType>::value,
|
||||||
bool SizeIsSymbolic =Symbolic::is_symbolic<SizeType>::value>
|
bool SizeIsSymbolic =Symbolic::is_symbolic<SizeType>::value>
|
||||||
struct aseq_reverse_first_type {
|
struct aseq_reverse_first_type {
|
||||||
typedef Index type;
|
typedef Index type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType>
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
struct aseq_reverse_first_type<FirstType,SizeType,true,true> {
|
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,true> {
|
||||||
typedef Symbolic::AddExpr<FirstType,
|
typedef Symbolic::AddExpr<FirstType,
|
||||||
Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr>,
|
Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr<fix_t<-1> > >,
|
||||||
Symbolic::ValueExpr>
|
Symbolic::ValueExpr<IncrType> >
|
||||||
> type;
|
> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType>
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
struct aseq_reverse_first_type<FirstType,SizeType,true,false> {
|
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,false> {
|
||||||
typedef Symbolic::AddExpr<FirstType,Symbolic::ValueExpr> type;
|
typedef Symbolic::AddExpr<FirstType,Symbolic::ValueExpr<> > type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType>
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
struct aseq_reverse_first_type<FirstType,SizeType,false,true> {
|
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,false,true> {
|
||||||
typedef Symbolic::AddExpr<Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr>,Symbolic::ValueExpr>,
|
typedef Symbolic::AddExpr<Symbolic::ProductExpr<Symbolic::AddExpr<SizeType,Symbolic::ValueExpr<fix_t<-1> > >,
|
||||||
Symbolic::ValueExpr> type;
|
Symbolic::ValueExpr<IncrType> >,
|
||||||
|
Symbolic::ValueExpr<> > type;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -127,17 +128,17 @@ protected:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
#if EIGEN_HAS_CXX11
|
||||||
auto reverse() const -> decltype(Eigen::seqN(m_first+(m_size-1)*Index(m_incr),m_size,-m_incr)) {
|
auto reverse() const -> decltype(Eigen::seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr)) {
|
||||||
return seqN(m_first+(m_size-1)*Index(m_incr),m_size,-m_incr);
|
return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
protected:
|
protected:
|
||||||
typedef typename internal::aseq_negate<IncrType>::type ReverseIncrType;
|
typedef typename internal::aseq_negate<IncrType>::type ReverseIncrType;
|
||||||
typedef typename internal::aseq_reverse_first_type<FirstType,SizeType>::type ReverseFirstType;
|
typedef typename internal::aseq_reverse_first_type<FirstType,SizeType,IncrType>::type ReverseFirstType;
|
||||||
public:
|
public:
|
||||||
ArithmeticSequence<ReverseFirstType,SizeType,ReverseIncrType>
|
ArithmeticSequence<ReverseFirstType,SizeType,ReverseIncrType>
|
||||||
reverse() const {
|
reverse() const {
|
||||||
return seqN(m_first+(m_size-1)*Index(m_incr),m_size,-m_incr);
|
return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -204,38 +205,40 @@ auto seq(FirstType f, LastType l, IncrType incr)
|
|||||||
return seqN(f,(l-f+CleanedIncrType(incr))/CleanedIncrType(incr),CleanedIncrType(incr));
|
return seqN(f,(l-f+CleanedIncrType(incr))/CleanedIncrType(incr),CleanedIncrType(incr));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<typename FirstType,typename LastType>
|
template<typename FirstType,typename LastType>
|
||||||
typename internal::enable_if<!(Symbolic::is_symbolic<FirstType>::value || Symbolic::is_symbolic<LastType>::value),
|
typename internal::enable_if<!(Symbolic::is_symbolic<FirstType>::value || Symbolic::is_symbolic<LastType>::value),
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index> >::type
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index> >::type
|
||||||
seq(FirstType f, LastType l)
|
seq(FirstType f, LastType l)
|
||||||
{
|
{
|
||||||
return seqN(f,(l-f+1));
|
return seqN(f,(l-f+fix<1>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FirstTypeDerived,typename LastType>
|
template<typename FirstTypeDerived,typename LastType>
|
||||||
typename internal::enable_if<!Symbolic::is_symbolic<LastType>::value,
|
typename internal::enable_if<!Symbolic::is_symbolic<LastType>::value,
|
||||||
ArithmeticSequence<FirstTypeDerived, Symbolic::AddExpr<Symbolic::AddExpr<Symbolic::NegateExpr<FirstTypeDerived>,Symbolic::ValueExpr>,
|
ArithmeticSequence<FirstTypeDerived, Symbolic::AddExpr<Symbolic::AddExpr<Symbolic::NegateExpr<FirstTypeDerived>,Symbolic::ValueExpr<> >,
|
||||||
Symbolic::ValueExpr> > >::type
|
Symbolic::ValueExpr<internal::fix_t<1> > > > >::type
|
||||||
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, LastType l)
|
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, LastType l)
|
||||||
{
|
{
|
||||||
return seqN(f.derived(),(l-f.derived()+1));
|
return seqN(f.derived(),(l-f.derived()+fix<1>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FirstType,typename LastTypeDerived>
|
template<typename FirstType,typename LastTypeDerived>
|
||||||
typename internal::enable_if<!Symbolic::is_symbolic<FirstType>::value,
|
typename internal::enable_if<!Symbolic::is_symbolic<FirstType>::value,
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
||||||
Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr>,Symbolic::ValueExpr> > >::type
|
Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr<> >,
|
||||||
|
Symbolic::ValueExpr<internal::fix_t<1> > > > >::type
|
||||||
seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l)
|
seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l)
|
||||||
{
|
{
|
||||||
return seqN(f,(l.derived()-f+1));
|
return seqN(f,(l.derived()-f+fix<1>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FirstTypeDerived,typename LastTypeDerived>
|
template<typename FirstTypeDerived,typename LastTypeDerived>
|
||||||
ArithmeticSequence<FirstTypeDerived,
|
ArithmeticSequence<FirstTypeDerived,
|
||||||
Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::NegateExpr<FirstTypeDerived> >,Symbolic::ValueExpr> >
|
Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::NegateExpr<FirstTypeDerived> >,Symbolic::ValueExpr<internal::fix_t<1> > > >
|
||||||
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l)
|
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l)
|
||||||
{
|
{
|
||||||
return seqN(f.derived(),(l.derived()-f.derived()+1));
|
return seqN(f.derived(),(l.derived()-f.derived()+fix<1>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -252,9 +255,9 @@ template<typename FirstTypeDerived,typename LastType, typename IncrType>
|
|||||||
typename internal::enable_if<!Symbolic::is_symbolic<LastType>::value,
|
typename internal::enable_if<!Symbolic::is_symbolic<LastType>::value,
|
||||||
ArithmeticSequence<FirstTypeDerived,
|
ArithmeticSequence<FirstTypeDerived,
|
||||||
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<Symbolic::NegateExpr<FirstTypeDerived>,
|
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<Symbolic::NegateExpr<FirstTypeDerived>,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr<> >,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
||||||
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, LastType l, IncrType incr)
|
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, LastType l, IncrType incr)
|
||||||
{
|
{
|
||||||
@ -265,9 +268,9 @@ seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, LastType l, IncrType incr)
|
|||||||
template<typename FirstType,typename LastTypeDerived, typename IncrType>
|
template<typename FirstType,typename LastTypeDerived, typename IncrType>
|
||||||
typename internal::enable_if<!Symbolic::is_symbolic<FirstType>::value,
|
typename internal::enable_if<!Symbolic::is_symbolic<FirstType>::value,
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
||||||
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr>,
|
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr<> >,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
||||||
seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
||||||
{
|
{
|
||||||
@ -279,8 +282,8 @@ template<typename FirstTypeDerived,typename LastTypeDerived, typename IncrType>
|
|||||||
ArithmeticSequence<FirstTypeDerived,
|
ArithmeticSequence<FirstTypeDerived,
|
||||||
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,
|
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,
|
||||||
Symbolic::NegateExpr<FirstTypeDerived> >,
|
Symbolic::NegateExpr<FirstTypeDerived> >,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type>
|
typename internal::cleanup_seq_incr<IncrType>::type>
|
||||||
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,7 @@ static const auto end = last+1;
|
|||||||
#else
|
#else
|
||||||
// Using a FixedExpr<1> expression is important here to make sure the compiler
|
// Using a FixedExpr<1> expression is important here to make sure the compiler
|
||||||
// can fully optimize the computation starting indices with zero overhead.
|
// can fully optimize the computation starting indices with zero overhead.
|
||||||
static const Symbolic::AddExpr<Symbolic::SymbolExpr<internal::symbolic_last_tag>,Symbolic::FixedExpr<1> > end(last+fix<1>());
|
static const Symbolic::AddExpr<Symbolic::SymbolExpr<internal::symbolic_last_tag>,Symbolic::ValueExpr<Eigen::internal::fix_t<1> > > end(last+fix<1>());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // end namespace placeholders
|
} // end namespace placeholders
|
||||||
|
@ -46,23 +46,24 @@ template<typename Arg1,typename Arg2> class AddExpr;
|
|||||||
template<typename Arg1,typename Arg2> class ProductExpr;
|
template<typename Arg1,typename Arg2> class ProductExpr;
|
||||||
template<typename Arg1,typename Arg2> class QuotientExpr;
|
template<typename Arg1,typename Arg2> class QuotientExpr;
|
||||||
|
|
||||||
// A simple wrapper around an Index to provide the eval method.
|
// A simple wrapper around an integral value to provide the eval method.
|
||||||
// We could also use a free-function symbolic_eval...
|
// We could also use a free-function symbolic_eval...
|
||||||
|
template<typename IndexType=Index>
|
||||||
class ValueExpr {
|
class ValueExpr {
|
||||||
public:
|
public:
|
||||||
ValueExpr(Index val) : m_value(val) {}
|
ValueExpr(IndexType val) : m_value(val) {}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Index eval_impl(const T&) const { return m_value; }
|
IndexType eval_impl(const T&) const { return m_value; }
|
||||||
protected:
|
protected:
|
||||||
Index m_value;
|
IndexType m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Simple wrapper around a compile-time value,
|
// Specialization for compile-time value,
|
||||||
// It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
|
// It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
|
||||||
template<int N>
|
template<int N>
|
||||||
class FixedExpr {
|
class ValueExpr<internal::fix_t<N> > {
|
||||||
public:
|
public:
|
||||||
FixedExpr() {}
|
ValueExpr() {}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Index eval_impl(const T&) const { return N; }
|
Index eval_impl(const T&) const { return N; }
|
||||||
};
|
};
|
||||||
@ -94,50 +95,49 @@ public:
|
|||||||
|
|
||||||
NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
|
NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
|
||||||
|
|
||||||
AddExpr<Derived,ValueExpr> operator+(Index b) const
|
AddExpr<Derived,ValueExpr<> > operator+(Index b) const
|
||||||
{ return AddExpr<Derived,ValueExpr >(derived(), b); }
|
{ return AddExpr<Derived,ValueExpr<> >(derived(), b); }
|
||||||
AddExpr<Derived,ValueExpr> operator-(Index a) const
|
AddExpr<Derived,ValueExpr<> > operator-(Index a) const
|
||||||
{ return AddExpr<Derived,ValueExpr >(derived(), -a); }
|
{ return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
|
||||||
ProductExpr<Derived,ValueExpr> operator*(Index a) const
|
ProductExpr<Derived,ValueExpr<> > operator*(Index a) const
|
||||||
{ return ProductExpr<Derived,ValueExpr>(derived(),a); }
|
{ return ProductExpr<Derived,ValueExpr<> >(derived(),a); }
|
||||||
QuotientExpr<Derived,ValueExpr> operator/(Index a) const
|
QuotientExpr<Derived,ValueExpr<> > operator/(Index a) const
|
||||||
{ return QuotientExpr<Derived,ValueExpr>(derived(),a); }
|
{ return QuotientExpr<Derived,ValueExpr<> >(derived(),a); }
|
||||||
|
|
||||||
friend AddExpr<Derived,ValueExpr> operator+(Index a, const BaseExpr& b)
|
|
||||||
{ return AddExpr<Derived,ValueExpr>(b.derived(), a); }
|
|
||||||
friend AddExpr<NegateExpr<Derived>,ValueExpr> operator-(Index a, const BaseExpr& b)
|
|
||||||
{ return AddExpr<NegateExpr<Derived>,ValueExpr>(-b.derived(), a); }
|
|
||||||
friend ProductExpr<ValueExpr,Derived> operator*(Index a, const BaseExpr& b)
|
|
||||||
{ return ProductExpr<ValueExpr,Derived>(a,b.derived()); }
|
|
||||||
friend QuotientExpr<ValueExpr,Derived> operator/(Index a, const BaseExpr& b)
|
|
||||||
{ return QuotientExpr<ValueExpr,Derived>(a,b.derived()); }
|
|
||||||
|
|
||||||
|
friend AddExpr<Derived,ValueExpr<> > operator+(Index a, const BaseExpr& b)
|
||||||
|
{ return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
|
||||||
|
friend AddExpr<NegateExpr<Derived>,ValueExpr<> > operator-(Index a, const BaseExpr& b)
|
||||||
|
{ return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
|
||||||
|
friend ProductExpr<ValueExpr<>,Derived> operator*(Index a, const BaseExpr& b)
|
||||||
|
{ return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
|
||||||
|
friend QuotientExpr<ValueExpr<>,Derived> operator/(Index a, const BaseExpr& b)
|
||||||
|
{ return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }
|
||||||
|
|
||||||
template<int N>
|
template<int N>
|
||||||
AddExpr<Derived,FixedExpr<N> > operator+(internal::fix_t<N>) const
|
AddExpr<Derived,ValueExpr<internal::fix_t<N> > > operator+(internal::fix_t<N>) const
|
||||||
{ return AddExpr<Derived,FixedExpr<N> >(derived(), FixedExpr<N>()); }
|
{ return AddExpr<Derived,ValueExpr<internal::fix_t<N> > >(derived(), ValueExpr<internal::fix_t<N> >()); }
|
||||||
template<int N>
|
template<int N>
|
||||||
AddExpr<Derived,FixedExpr<N> > operator-(internal::fix_t<N>) const
|
AddExpr<Derived,ValueExpr<internal::fix_t<N> > > operator-(internal::fix_t<N>) const
|
||||||
{ return AddExpr<Derived,FixedExpr<-N> >(derived(), FixedExpr<-N>()); }
|
{ return AddExpr<Derived,ValueExpr<internal::fix_t<-N> > >(derived(), ValueExpr<internal::fix_t<-N> >()); }
|
||||||
template<int N>
|
template<int N>
|
||||||
ProductExpr<Derived,FixedExpr<N> > operator*(internal::fix_t<N>) const
|
ProductExpr<Derived,ValueExpr<internal::fix_t<N> > > operator*(internal::fix_t<N>) const
|
||||||
{ return ProductExpr<Derived,FixedExpr<N> >(derived(),FixedExpr<N>()); }
|
{ return ProductExpr<Derived,ValueExpr<internal::fix_t<N> > >(derived(),ValueExpr<internal::fix_t<N> >()); }
|
||||||
template<int N>
|
template<int N>
|
||||||
QuotientExpr<Derived,FixedExpr<N> > operator/(internal::fix_t<N>) const
|
QuotientExpr<Derived,ValueExpr<internal::fix_t<N> > > operator/(internal::fix_t<N>) const
|
||||||
{ return QuotientExpr<Derived,FixedExpr<N> >(derived(),FixedExpr<N>()); }
|
{ return QuotientExpr<Derived,ValueExpr<internal::fix_t<N> > >(derived(),ValueExpr<internal::fix_t<N> >()); }
|
||||||
|
|
||||||
template<int N>
|
template<int N>
|
||||||
friend AddExpr<Derived,FixedExpr<N> > operator+(internal::fix_t<N>, const BaseExpr& b)
|
friend AddExpr<Derived,ValueExpr<internal::fix_t<N> > > operator+(internal::fix_t<N>, const BaseExpr& b)
|
||||||
{ return AddExpr<Derived,FixedExpr<N> >(b.derived(), FixedExpr<N>()); }
|
{ return AddExpr<Derived,ValueExpr<internal::fix_t<N> > >(b.derived(), ValueExpr<internal::fix_t<N> >()); }
|
||||||
template<int N>
|
template<int N>
|
||||||
friend AddExpr<NegateExpr<Derived>,FixedExpr<N> > operator-(internal::fix_t<N>, const BaseExpr& b)
|
friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::fix_t<N> > > operator-(internal::fix_t<N>, const BaseExpr& b)
|
||||||
{ return AddExpr<NegateExpr<Derived>,FixedExpr<N> >(-b.derived(), FixedExpr<N>()); }
|
{ return AddExpr<NegateExpr<Derived>,ValueExpr<internal::fix_t<N> > >(-b.derived(), ValueExpr<internal::fix_t<N> >()); }
|
||||||
template<int N>
|
template<int N>
|
||||||
friend ProductExpr<FixedExpr<N>,Derived> operator*(internal::fix_t<N>, const BaseExpr& b)
|
friend ProductExpr<ValueExpr<internal::fix_t<N> >,Derived> operator*(internal::fix_t<N>, const BaseExpr& b)
|
||||||
{ return ProductExpr<FixedExpr<N>,Derived>(FixedExpr<N>(),b.derived()); }
|
{ return ProductExpr<ValueExpr<internal::fix_t<N> >,Derived>(ValueExpr<internal::fix_t<N> >(),b.derived()); }
|
||||||
template<int N>
|
template<int N>
|
||||||
friend QuotientExpr<FixedExpr<N>,Derived> operator/(internal::fix_t<N>, const BaseExpr& b)
|
friend QuotientExpr<ValueExpr<internal::fix_t<N> >,Derived> operator/(internal::fix_t<N>, const BaseExpr& b)
|
||||||
{ return QuotientExpr<FixedExpr<N> ,Derived>(FixedExpr<N>(),b.derived()); }
|
{ return QuotientExpr<ValueExpr<internal::fix_t<N> > ,Derived>(ValueExpr<internal::fix_t<N> >(),b.derived()); }
|
||||||
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user