File CloneInterface.h

Copyright

This code is licensed under the 3-clause BSD license.

Copyright ETH Zurich, Laboratory for Physical Chemistry, Reiher Group.

See LICENSE.txt for details.

namespace Scine

This header file contains functions that allow for common notation for common things that can be done at a different degree of derivatives.

This header contains alias definitions defining which classes to use for the different degrees of derivatives.

namespace Utils
template<class T>
class Abstract
#include <CloneInterface.h>

Strong typing for the abstract level class.

To provide template parameter resolution at compile time, a strong type is provided to differentiate the leaf class from the abstract, middle class.

template<class Derived, class ...Bases>
class CloneInterface : public Bases
#include <CloneInterface.h>

Class serving the purpose of a generic clone interface.

This class provides the clone method for any interface in core needing it. It uses the curiously recurrent template pattern (CRTP) to acquire infos at compile time about both the interface and the derived class. This allows for the one-time-only generation of code for the clone method, avoiding unnecessary code duplication. Basically, a derived class must just inherit from the CloneInterface with template parameters Derived = derived class and Base = interface class to have a functioning clone method. See https://www.fluentcpp.com/2017/09/12/how-to-return-a-smart-pointer-and-use-covariance/ for further details.

Note that classes deriving from CloneInterface<Derived, Base> do implicitly derive from Base, hence they do not need an additional ‘public Base’ statement.

Public Functions

~CloneInterface()
std::unique_ptr<Derived> clone() const

Templetized clone method, it hides the interface clone method.

Return

A unique_ptr to the derived class. This function allows for working directly with the derived class if the type is known. It hides the Base class’ clone() method (does not override it!). This is achieved with templetized Derived and Base classes.

Template Parameters
  • Derived: The type of the derived class.

Private Functions

CloneInterface *cloneImpl() const
template<class Derived, class ...Bases>
class CloneInterface<Abstract<Derived>, Bases...> : public Bases
#include <CloneInterface.h>

Specialization for abstract classes.

This is necessary, because otherwise the inheritance pattern would not work. It would not be necessary if the inheritance would just have 2 level: interface class and derived class. From the moment that there are also abstract classes between interface and derived class, as the Core::Calculator in the Sparrow module is the most notorious example, the cloneImpl() method must be virtualized in the abstract class.

Public Functions

~CloneInterface()
std::unique_ptr<Derived> clone() const

Private Functions

CloneInterface *cloneImpl() const = 0