Skip to content

Add a wrapper to provide copy/move operations

Simon Praetorius requested to merge feature/copy-wrapper into master

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

Merge request reports