mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: expand VectorSpaceOps to include copy_n/fill_n methods
- similar to what std::copy_n and std::fill_n would do, except with
templated loops. This allows compile-time transcribing with loop
unrolling. For example,
vector vec1 = ..., vec2 = ...;
FixedList<scalar, 6> values;
VectorSpaceOps<3>::copy_n(vec1.begin(), values.begin());
VectorSpaceOps<3>::copy_n(vec2.begin(), values.begin(3))
// do something with all of these values
STYLE: make start index of VectorSpaceOps optional
ENH: add clamped begin(int) versions to FixedList as per UList
This commit is contained in:
@ -1,3 +1,3 @@
|
|||||||
Test-vector.C
|
Test-vector.cxx
|
||||||
|
|
||||||
EXE = $(FOAM_USER_APPBIN)/Test-vector
|
EXE = $(FOAM_USER_APPBIN)/Test-vector
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,7 +32,10 @@ Description
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "vectorField.H"
|
#include "vectorField.H"
|
||||||
|
#include "boolVector.H"
|
||||||
|
#include "labelVector.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
|
#include "FixedList.H"
|
||||||
#include "Random.H"
|
#include "Random.H"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <random>
|
#include <random>
|
||||||
@ -125,6 +128,42 @@ void testNormalise(Field<Type>& fld)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Transcribe vectorspace information into a FixedList
|
||||||
|
template<class Type>
|
||||||
|
void testTranscribe(Type& input)
|
||||||
|
{
|
||||||
|
if constexpr
|
||||||
|
(
|
||||||
|
is_vectorspace_v<Type>
|
||||||
|
&& std::is_floating_point_v<typename pTraits_cmptType<Type>::type>
|
||||||
|
)
|
||||||
|
{
|
||||||
|
constexpr auto nCmpts = pTraits_nComponents<Type>::value;
|
||||||
|
using cmpt = typename pTraits_cmptType<Type>::type;
|
||||||
|
|
||||||
|
FixedList<cmpt, nCmpts+1> values;
|
||||||
|
values.back() = 100; // some additional data
|
||||||
|
|
||||||
|
VectorSpaceOps<nCmpts>::copy_n(input.cdata(), values.data());
|
||||||
|
|
||||||
|
Info<< "Transcribed " << input << " => " << values << nl;
|
||||||
|
|
||||||
|
for (auto& val : values)
|
||||||
|
{
|
||||||
|
val *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorSpaceOps<nCmpts>::copy_n(values.cdata(), input.data());
|
||||||
|
Info<< " copied back (-1) as " << input
|
||||||
|
<< " from " << values << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Did not transcribe " << input << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
// Main program:
|
// Main program:
|
||||||
|
|
||||||
@ -240,6 +279,16 @@ int main(int argc, char *argv[])
|
|||||||
testNormalise(vfld2);
|
testNormalise(vfld2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Test transcribing components" << nl;
|
||||||
|
{
|
||||||
|
vector vec1(1.1, 2.2, 3.3);
|
||||||
|
testTranscribe(vec1);
|
||||||
|
|
||||||
|
labelVector vec2(10, 20, 30);
|
||||||
|
testTranscribe(vec2);
|
||||||
|
}
|
||||||
|
|
||||||
Info<< "\nEnd\n" << nl;
|
Info<< "\nEnd\n" << nl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1,3 +1,3 @@
|
|||||||
Test-vectorTools.C
|
Test-vectorTools.cxx
|
||||||
|
|
||||||
EXE = $(FOAM_USER_APPBIN)/Test-vectorTools
|
EXE = $(FOAM_USER_APPBIN)/Test-vectorTools
|
||||||
|
|||||||
@ -384,6 +384,10 @@ public:
|
|||||||
//- Return an iterator to end traversing the FixedList
|
//- Return an iterator to end traversing the FixedList
|
||||||
inline iterator end() noexcept;
|
inline iterator end() noexcept;
|
||||||
|
|
||||||
|
//- Return iterator at offset i from begin,
|
||||||
|
//- clamped to [0,N] range
|
||||||
|
inline iterator begin(const int i) noexcept;
|
||||||
|
|
||||||
|
|
||||||
// Random access iterator (const)
|
// Random access iterator (const)
|
||||||
|
|
||||||
@ -399,6 +403,14 @@ public:
|
|||||||
//- Return const_iterator to end traversing the constant FixedList
|
//- Return const_iterator to end traversing the constant FixedList
|
||||||
inline const_iterator end() const noexcept;
|
inline const_iterator end() const noexcept;
|
||||||
|
|
||||||
|
//- Return const_iterator at offset i from begin,
|
||||||
|
//- clamped to [0,N] range
|
||||||
|
inline const_iterator cbegin(const int i) const noexcept;
|
||||||
|
|
||||||
|
//- Return const_iterator at offset i from begin,
|
||||||
|
//- clamped to [0,N] range
|
||||||
|
inline const_iterator begin(const int i) const noexcept;
|
||||||
|
|
||||||
|
|
||||||
// Reverse iterator (non-const)
|
// Reverse iterator (non-const)
|
||||||
|
|
||||||
|
|||||||
@ -499,6 +499,30 @@ Foam::FixedList<T, N>::cbegin() const noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned N>
|
||||||
|
inline typename Foam::FixedList<T, N>::iterator
|
||||||
|
Foam::FixedList<T, N>::begin(const int i) noexcept
|
||||||
|
{
|
||||||
|
return (v_ + (i < 0 ? 0 : int(N) < i ? int(N) : i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned N>
|
||||||
|
inline typename Foam::FixedList<T, N>::const_iterator
|
||||||
|
Foam::FixedList<T, N>::begin(const int i) const noexcept
|
||||||
|
{
|
||||||
|
return (v_ + (i < 0 ? 0 : int(N) < i ? int(N) : i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned N>
|
||||||
|
inline typename Foam::FixedList<T, N>::const_iterator
|
||||||
|
Foam::FixedList<T, N>::cbegin(const int i) const noexcept
|
||||||
|
{
|
||||||
|
return (v_ + (i < 0 ? 0 : int(N) < i ? int(N) : i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, unsigned N>
|
template<class T, unsigned N>
|
||||||
inline typename Foam::FixedList<T, N>::iterator
|
inline typename Foam::FixedList<T, N>::iterator
|
||||||
Foam::FixedList<T, N>::end() noexcept
|
Foam::FixedList<T, N>::end() noexcept
|
||||||
|
|||||||
@ -158,7 +158,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct initialized to zero
|
//- Construct initialized to zero
|
||||||
inline VectorSpace(const Foam::zero);
|
inline VectorSpace(Foam::zero);
|
||||||
|
|
||||||
//- Copy construct
|
//- Copy construct
|
||||||
inline VectorSpace(const VectorSpace<Form, Cmpt, Ncmpts>& vs);
|
inline VectorSpace(const VectorSpace<Form, Cmpt, Ncmpts>& vs);
|
||||||
@ -174,10 +174,7 @@ public:
|
|||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- The number of elements in the VectorSpace = Ncmpts.
|
//- The number of elements in the VectorSpace = Ncmpts.
|
||||||
static constexpr direction size() noexcept
|
static constexpr direction size() noexcept { return Ncmpts; }
|
||||||
{
|
|
||||||
return Ncmpts;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const Cmpt& component(const direction) const;
|
inline const Cmpt& component(const direction) const;
|
||||||
inline Cmpt& component(const direction);
|
inline Cmpt& component(const direction);
|
||||||
@ -186,10 +183,10 @@ public:
|
|||||||
inline void replace(const direction, const Cmpt&);
|
inline void replace(const direction, const Cmpt&);
|
||||||
|
|
||||||
//- Return const pointer to the first data element
|
//- Return const pointer to the first data element
|
||||||
inline const Cmpt* cdata() const noexcept;
|
const Cmpt* cdata() const noexcept { return v_; }
|
||||||
|
|
||||||
//- Return pointer to the first data element
|
//- Return pointer to the first data element
|
||||||
inline Cmpt* data() noexcept;
|
Cmpt* data() noexcept { return v_; }
|
||||||
|
|
||||||
//- Assign all components to given value
|
//- Assign all components to given value
|
||||||
inline void fill(const Cmpt& s);
|
inline void fill(const Cmpt& s);
|
||||||
@ -210,7 +207,7 @@ public:
|
|||||||
inline void operator+=(const VectorSpace<Form, Cmpt, Ncmpts>&);
|
inline void operator+=(const VectorSpace<Form, Cmpt, Ncmpts>&);
|
||||||
inline void operator-=(const VectorSpace<Form, Cmpt, Ncmpts>&);
|
inline void operator-=(const VectorSpace<Form, Cmpt, Ncmpts>&);
|
||||||
|
|
||||||
inline void operator=(const Foam::zero);
|
inline void operator=(Foam::zero);
|
||||||
inline void operator*=(const scalar);
|
inline void operator*=(const scalar);
|
||||||
inline void operator/=(const scalar);
|
inline void operator/=(const scalar);
|
||||||
|
|
||||||
@ -224,28 +221,25 @@ public:
|
|||||||
typedef const Cmpt* const_iterator;
|
typedef const Cmpt* const_iterator;
|
||||||
|
|
||||||
|
|
||||||
// Random access iterator (non-const)
|
// Random access iterators (const and non-const)
|
||||||
|
|
||||||
//- Return an iterator to begin of VectorSpace
|
//- Return an iterator (pointer) to begin of VectorSpace
|
||||||
inline iterator begin() noexcept;
|
iterator begin() noexcept { return v_; }
|
||||||
|
|
||||||
//- Return an iterator to end of VectorSpace
|
//- Return const_iterator (const pointer) to begin of VectorSpace
|
||||||
inline iterator end() noexcept;
|
const_iterator begin() const noexcept { return v_; }
|
||||||
|
|
||||||
|
//- Return const_iterator (const pointer) to begin of VectorSpace
|
||||||
|
const_iterator cbegin() const noexcept { return v_; }
|
||||||
|
|
||||||
// Random access iterator (const)
|
//- Return an iterator (pointer) to end of VectorSpace
|
||||||
|
iterator end() noexcept { return (v_ + Ncmpts); }
|
||||||
|
|
||||||
//- Return const_iterator to begin of VectorSpace
|
//- Return const_iterator (const pointer) to end of VectorSpace
|
||||||
inline const_iterator cbegin() const noexcept;
|
const_iterator end() const noexcept { return (v_ + Ncmpts); }
|
||||||
|
|
||||||
//- Return const_iterator to end of VectorSpace
|
//- Return const_iterator (const pointer) to end of VectorSpace
|
||||||
inline const_iterator cend() const noexcept;
|
const_iterator cend() const noexcept { return (v_ + Ncmpts); }
|
||||||
|
|
||||||
//- Return const_iterator to begin of VectorSpace
|
|
||||||
inline const_iterator begin() const noexcept;
|
|
||||||
|
|
||||||
//- Return const_iterator to end of VectorSpace
|
|
||||||
inline const_iterator end() const noexcept;
|
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operators
|
// IOstream Operators
|
||||||
|
|||||||
@ -35,9 +35,9 @@ License
|
|||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
||||||
inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace(const Foam::zero)
|
inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace(Foam::zero)
|
||||||
{
|
{
|
||||||
VectorSpaceOps<Ncmpts,0>::eqOpS(*this, Zero, eqOp<Cmpt>());
|
VectorSpaceOps<Ncmpts>::fill_n(this->begin(), Cmpt(Foam::zero{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace
|
|||||||
const VectorSpace<Form, Cmpt, Ncmpts>& vs
|
const VectorSpace<Form, Cmpt, Ncmpts>& vs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VectorSpaceOps<Ncmpts,0>::eqOp(*this, vs, eqOp<Cmpt>());
|
VectorSpaceOps<Ncmpts>::copy_n(vs.cbegin(), this->begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ inline Foam::VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace
|
|||||||
const VectorSpace<Form2, Cmpt2, Ncmpts>& vs
|
const VectorSpace<Form2, Cmpt2, Ncmpts>& vs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VectorSpaceOps<Ncmpts,0>::eqOp(*this, vs, eqOp<Cmpt>());
|
VectorSpaceOps<Ncmpts>::copy_n(vs.cbegin(), this->begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::replace
|
|||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
||||||
inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::fill(const Cmpt& s)
|
inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::fill(const Cmpt& s)
|
||||||
{
|
{
|
||||||
VectorSpaceOps<Ncmpts,0>::eqOpS(*this, s, eqOp<Cmpt>());
|
VectorSpaceOps<Ncmpts>::fill_n(this->begin(), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|||||||
inline Form Foam::VectorSpace<Form, Cmpt, Ncmpts>::uniform(const Cmpt& s)
|
inline Form Foam::VectorSpace<Form, Cmpt, Ncmpts>::uniform(const Cmpt& s)
|
||||||
{
|
{
|
||||||
Form v;
|
Form v;
|
||||||
VectorSpaceOps<Ncmpts,0>::eqOpS(v, s, eqOp<Cmpt>());
|
v.fill(s);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,68 +186,6 @@ Foam::VectorSpace<Form, Cmpt, Ncmpts>::block() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Iterator * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::data() noexcept
|
|
||||||
{
|
|
||||||
return v_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::cdata() const noexcept
|
|
||||||
{
|
|
||||||
return v_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::begin() noexcept
|
|
||||||
{
|
|
||||||
return v_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::end() noexcept
|
|
||||||
{
|
|
||||||
return (v_ + Ncmpts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::cbegin()
|
|
||||||
const noexcept
|
|
||||||
{
|
|
||||||
return v_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::cend()
|
|
||||||
const noexcept
|
|
||||||
{
|
|
||||||
return (v_ + Ncmpts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::begin()
|
|
||||||
const noexcept
|
|
||||||
{
|
|
||||||
return v_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
|
||||||
inline const Cmpt* Foam::VectorSpace<Form, Cmpt, Ncmpts>::end()
|
|
||||||
const noexcept
|
|
||||||
{
|
|
||||||
return (v_ + Ncmpts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
||||||
@ -346,7 +284,7 @@ inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator=
|
|||||||
const VectorSpace<Form, Cmpt, Ncmpts>& vs
|
const VectorSpace<Form, Cmpt, Ncmpts>& vs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VectorSpaceOps<Ncmpts,0>::eqOp(*this, vs, eqOp<Cmpt>());
|
VectorSpaceOps<Ncmpts>::copy_n(vs.cbegin(), this->begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -371,9 +309,9 @@ inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator-=
|
|||||||
|
|
||||||
|
|
||||||
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
template<class Form, class Cmpt, Foam::direction Ncmpts>
|
||||||
inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator=(const Foam::zero)
|
inline void Foam::VectorSpace<Form, Cmpt, Ncmpts>::operator=(Foam::zero)
|
||||||
{
|
{
|
||||||
VectorSpaceOps<Ncmpts,0>::eqOpS(*this, 0, eqOp<Cmpt>());
|
VectorSpaceOps<Ncmpts>::fill_n(this->begin(), Cmpt(Foam::zero{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -43,9 +43,40 @@ namespace Foam
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//- Recursive execution. Terminating at \<N\>, starting at index \<I\>
|
//- Recursive execution. Terminating at \<N\>, starting at index \<I\>
|
||||||
template<direction N, direction I>
|
template<direction N, direction I=0>
|
||||||
struct VectorSpaceOps
|
struct VectorSpaceOps
|
||||||
{
|
{
|
||||||
|
//- Somewhat equivalent to std::copy_n() but with templated loops.
|
||||||
|
// \param [in] input indexable input data
|
||||||
|
// \param [out] result indexable output data
|
||||||
|
template<class Input, class Output>
|
||||||
|
static inline void copy_n(Input input, Output result)
|
||||||
|
{
|
||||||
|
// if constexpr (I < N)
|
||||||
|
{
|
||||||
|
result[I] = input[I];
|
||||||
|
VectorSpaceOps<N, I+1>::copy_n(input, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Somewhat equivalent to std::fill_n() but with templated loops
|
||||||
|
// \param [out] result indexable output data
|
||||||
|
// \param val the value to assign for each entry
|
||||||
|
template<class Output, class T>
|
||||||
|
static inline void fill_n(Output result, const T& val)
|
||||||
|
{
|
||||||
|
// if constexpr (I < N)
|
||||||
|
{
|
||||||
|
result[I] = val;
|
||||||
|
VectorSpaceOps<N, I+1>::fill_n(result, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Apply the binary assignment operation to each vector-space
|
||||||
|
//- component.
|
||||||
|
// \param [in,out] vs vector-space (indexed) data
|
||||||
|
// \param s scalar/component data (non-indexed)
|
||||||
|
// \param eo binary combine/assign operation
|
||||||
template<class V, class S, class EqOp>
|
template<class V, class S, class EqOp>
|
||||||
static inline void eqOpS(V& vs, const S& s, EqOp eo)
|
static inline void eqOpS(V& vs, const S& s, EqOp eo)
|
||||||
{
|
{
|
||||||
@ -56,6 +87,10 @@ struct VectorSpaceOps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Apply the inplace binary reduction operation.
|
||||||
|
// \param [in,out] s scalar or component data (non-indexed)
|
||||||
|
// \param [in] vs input vector-space (indexed) data
|
||||||
|
// \param eo binary combine/assign operation
|
||||||
template<class S, class V, class EqOp>
|
template<class S, class V, class EqOp>
|
||||||
static inline void SeqOp(S& s, const V& vs, EqOp eo)
|
static inline void SeqOp(S& s, const V& vs, EqOp eo)
|
||||||
{
|
{
|
||||||
@ -66,6 +101,10 @@ struct VectorSpaceOps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Apply the inplace binary assignment operation to the components.
|
||||||
|
// \param [in,out] vs1 vector-space (indexed) data
|
||||||
|
// \param [in] vs2 second vector-space (indexed) data
|
||||||
|
// \param eo binary combine/assign operation
|
||||||
template<class V1, class V2, class EqOp>
|
template<class V1, class V2, class EqOp>
|
||||||
static inline void eqOp(V1& vs1, const V2& vs2, EqOp eo)
|
static inline void eqOp(V1& vs1, const V2& vs2, EqOp eo)
|
||||||
{
|
{
|
||||||
@ -76,34 +115,51 @@ struct VectorSpaceOps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Apply the binary operation between vector-space and scalar data
|
||||||
template<class V, class V1, class S, class Op>
|
//- and assign the result.
|
||||||
static inline void opVS(V& vs, const V1& vs1, const S& s, Op o)
|
// \param [out] vs vector-space (indexed) data
|
||||||
|
// \param [in] vs1 vector-space (indexed) data operand
|
||||||
|
// \param [in] s scalar operand
|
||||||
|
// \param bop binary operation
|
||||||
|
template<class V, class V1, class S, class BinaryOp>
|
||||||
|
static inline void opVS(V& vs, const V1& vs1, const S& s, BinaryOp bop)
|
||||||
{
|
{
|
||||||
// if constexpr (I < N)
|
// if constexpr (I < N)
|
||||||
{
|
{
|
||||||
vs.v_[I] = o(vs1.v_[I], s);
|
vs.v_[I] = bop(vs1.v_[I], s);
|
||||||
VectorSpaceOps<N, I+1>::opVS(vs, vs1, s, o);
|
VectorSpaceOps<N, I+1>::opVS(vs, vs1, s, bop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class V, class S, class V1, class Op>
|
//- Apply the binary operation between scalar and vector-space data
|
||||||
static inline void opSV(V& vs, const S& s, const V1& vs1, Op o)
|
//- and assign the result.
|
||||||
|
// \param [out] vs vector-space (indexed) data
|
||||||
|
// \param [in] s scalar operand
|
||||||
|
// \param [in] vs1 vector-space (indexed) data operand
|
||||||
|
// \param bop binary operation
|
||||||
|
template<class V, class S, class V1, class BinaryOp>
|
||||||
|
static inline void opSV(V& vs, const S& s, const V1& vs1, BinaryOp bop)
|
||||||
{
|
{
|
||||||
// if constexpr (I < N)
|
// if constexpr (I < N)
|
||||||
{
|
{
|
||||||
vs.v_[I] = o(s, vs1.v_[I]);
|
vs.v_[I] = bop(s, vs1.v_[I]);
|
||||||
VectorSpaceOps<N, I+1>::opSV(vs, s, vs1, o);
|
VectorSpaceOps<N, I+1>::opSV(vs, s, vs1, bop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class V, class V1, class Op>
|
//- Apply the binary operation between two vector-space data
|
||||||
static inline void op(V& vs, const V1& vs1, const V1& vs2, Op o)
|
//- and assign the result.
|
||||||
|
// \param [out] vs vector-space (indexed) data
|
||||||
|
// \param [in] vs1 vector-space (indexed) data operand
|
||||||
|
// \param [in] vs2 vector-space (indexed) data operand
|
||||||
|
// \param bop binary operation
|
||||||
|
template<class V, class V1, class BinaryOp>
|
||||||
|
static inline void op(V& vs, const V1& vs1, const V1& vs2, BinaryOp bop)
|
||||||
{
|
{
|
||||||
// if constexpr (I < N)
|
// if constexpr (I < N)
|
||||||
{
|
{
|
||||||
vs.v_[I] = o(vs1.v_[I], vs2.v_[I]);
|
vs.v_[I] = bop(vs1.v_[I], vs2.v_[I]);
|
||||||
VectorSpaceOps<N, I+1>::op(vs, vs1, vs2, o);
|
VectorSpaceOps<N, I+1>::op(vs, vs1, vs2, bop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -115,6 +171,12 @@ struct VectorSpaceOps
|
|||||||
template<direction N>
|
template<direction N>
|
||||||
struct VectorSpaceOps<N, N>
|
struct VectorSpaceOps<N, N>
|
||||||
{
|
{
|
||||||
|
template<class Input, class Output>
|
||||||
|
static inline void copy_n(Input, Output) {}
|
||||||
|
|
||||||
|
template<class Output, class T>
|
||||||
|
static inline void fill_n(Output, const T&) {}
|
||||||
|
|
||||||
template<class V, class S, class EqOp>
|
template<class V, class S, class EqOp>
|
||||||
static inline void eqOpS(V&, const S&, EqOp) {}
|
static inline void eqOpS(V&, const S&, EqOp) {}
|
||||||
|
|
||||||
@ -124,14 +186,14 @@ struct VectorSpaceOps<N, N>
|
|||||||
template<class V1, class V2, class EqOp>
|
template<class V1, class V2, class EqOp>
|
||||||
static inline void eqOp(V1&, const V2&, EqOp) {}
|
static inline void eqOp(V1&, const V2&, EqOp) {}
|
||||||
|
|
||||||
template<class V, class V1, class S, class Op>
|
template<class V, class V1, class S, class BinaryOp>
|
||||||
static inline void opVS(V& vs, const V1&, const S&, Op) {}
|
static inline void opVS(V&, const V1&, const S&, BinaryOp) {}
|
||||||
|
|
||||||
template<class V, class S, class V1, class Op>
|
template<class V, class S, class V1, class BinaryOp>
|
||||||
static inline void opSV(V& vs, const S&, const V1&, Op) {}
|
static inline void opSV(V&, const S&, const V1&, BinaryOp) {}
|
||||||
|
|
||||||
template<class V, class V1, class Op>
|
template<class V, class V1, class BinaryOp>
|
||||||
static inline void op(V& vs, const V1&, const V1&, Op) {}
|
static inline void op(V&, const V1&, const V1&, BinaryOp) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user