fix: use perfect forwarding in forges
- Avoid some cases of implicit copy instead of correct reference forwarding. - Use C++-17's make_from_tuple instead of the previous complex machinery.
This commit is contained in:
parent
dff32c9a96
commit
d27aad810d
1 changed files with 12 additions and 28 deletions
|
|
@ -101,8 +101,8 @@ template<class Itf, class Op, typename... Args>
|
||||||
class eoForgeOperator : public eoForgeInterface<Itf>
|
class eoForgeOperator : public eoForgeInterface<Itf>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
eoForgeOperator(Args... args) :
|
eoForgeOperator(Args&&... args) :
|
||||||
_args(args...),
|
_args(std::forward<Args>(args)...),
|
||||||
_instanciated(nullptr)
|
_instanciated(nullptr)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ class eoForgeOperator : public eoForgeInterface<Itf>
|
||||||
if(_instanciated) {
|
if(_instanciated) {
|
||||||
delete _instanciated;
|
delete _instanciated;
|
||||||
}
|
}
|
||||||
_instanciated = constructor(_args);
|
_instanciated = op_constructor(_args);
|
||||||
}
|
}
|
||||||
return *_instanciated;
|
return *_instanciated;
|
||||||
}
|
}
|
||||||
|
|
@ -131,31 +131,15 @@ class eoForgeOperator : public eoForgeInterface<Itf>
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::tuple<Args...> _args;
|
std::tuple<Args&&...> _args;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Metaprogramming machinery which deals with arguments lists @{ */
|
/** Metaprogramming machinery which deals with arguments lists @{ */
|
||||||
template <int... Idx>
|
template<class T>
|
||||||
struct index {};
|
Op* op_constructor(T& args)
|
||||||
|
|
||||||
template <int N, int... Idx>
|
|
||||||
struct gen_seq : gen_seq<N - 1, N - 1, Idx...> {};
|
|
||||||
|
|
||||||
template <int... Idx>
|
|
||||||
struct gen_seq<0, Idx...> : index<Idx...> {};
|
|
||||||
|
|
||||||
template <typename... Ts, int... Idx>
|
|
||||||
Op* constructor(std::tuple<Ts...>& args, index<Idx...>)
|
|
||||||
{
|
{
|
||||||
Op* p_op = new Op(std::get<Idx>(args)...);
|
// FIXME double-check that the copy-constructor is a good idea to make_from_tuple with dynamic storage duration.
|
||||||
_instanciated = p_op;
|
return new Op(std::make_from_tuple<Op>(args));
|
||||||
return p_op;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
Op* constructor(std::tuple<Ts...>& args)
|
|
||||||
{
|
|
||||||
return constructor(args, gen_seq<sizeof...(Ts)>{});
|
|
||||||
}
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
@ -243,9 +227,9 @@ class eoForgeVector : public std::vector<eoForgeInterface<Itf>*>
|
||||||
/** Add an operator to the list.
|
/** Add an operator to the list.
|
||||||
*/
|
*/
|
||||||
template<class Op, typename... Args>
|
template<class Op, typename... Args>
|
||||||
void add(Args... args)
|
void add(Args&&... args)
|
||||||
{
|
{
|
||||||
auto pfo = new eoForgeOperator<Itf,Op,Args...>(args...);
|
auto pfo = new eoForgeOperator<Itf,Op,Args...>(std::forward<Args>(args)...);
|
||||||
this->push_back(pfo);
|
this->push_back(pfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,11 +247,11 @@ class eoForgeVector : public std::vector<eoForgeInterface<Itf>*>
|
||||||
* @warning The operator at `index` should have been added with eoForgeVector::add already..
|
* @warning The operator at `index` should have been added with eoForgeVector::add already..
|
||||||
*/
|
*/
|
||||||
template<class Op, typename... Args>
|
template<class Op, typename... Args>
|
||||||
void setup(size_t index, Args... args)
|
void setup(size_t index, Args&&... args)
|
||||||
{
|
{
|
||||||
assert(index < this->size());
|
assert(index < this->size());
|
||||||
delete this->at(index); // Silent on nullptr.
|
delete this->at(index); // Silent on nullptr.
|
||||||
auto pfo = new eoForgeOperator<Itf,Op,Args...>(args...);
|
auto pfo = new eoForgeOperator<Itf,Op,Args...>(std::forward<Args>(args)...);
|
||||||
this->at(index) = pfo;
|
this->at(index) = pfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue