Add a wrapper to provide copy/move operations
Summary
This MR adds a class that extends the interface of a type by copy and move operations. Conditionally a default constructor is provided. It works as follows:
- If the type provides a copy/move constructor, the copy/move assignment operations are implemented in terms of construction
- If the type provides a default constructor also the wrapper implement the default constructor that default initializes the stored object.
Essentially this is an extension of std::optional
with the explicit implementation of assignment and default construction. See https://en.cppreference.com/w/cpp/ranges/copyable_wrapper for a corresponding c++20 implementation in the standard library
Example of usage
template <class F>
class FunctionWrapper
{
public:
FunctionWrapper (const F& fct)
: fct_{fct}
{}
// implement the evaluation operator to provide a functor interface
template <class... Args>
decltype(auto) operator() (Args&&... args) const
{
return (*fct_)(std::forward<Args>(args)...);
}
private:
CopyableOptional<F> fct_;
};
// ...
auto f = [...](auto const& x) { return x[0] * x[1]; };
auto g = FunctionWrapper{f};
auto g2 = g; // copy constructor
auto g3 = std::move(g2); // move constructor
g2 = g3; // copy assignment
g3 = std::move(g2); // move assignment
auto y = g3(x); // evaluation
Applications
Several types in Dune are not (yet) copy assignable, while already copy constructible. Sometimes this is an oversight and should be fixed, but this takes time. This wrapper might be used in a transition time. Other (non-dune) cannot be fixed.
- (Geometry types are not default constructible)
- LagrangeLocalFiniteElementCache is not copy-assignable
- Lambda expressions are not copy-assignable
TODO
-
Add tests for the wrapper -
Add a changelog entry -
Squash commits
Edited by Simon Praetorius