ClassName::ClassName(ClassName##Impl &&impl)                                                                       \
        : m_impl{ std::make_shared<ClassName##Impl>(std::move(impl)) }                                                 \
    {}                                                                                                                 \
                                                                                                                       \
    ClassName##Impl &ClassName::getImpl()                                                                              \
    {                                                                                                                  \
        return *m_impl;                                                                                                \
    }                                                                                                                  \
                                                                                                                       \
    const ClassName##Impl &ClassName::getImpl() const                                                                  \
    {                                                                                                                  \
        return *m_impl;                                                                                                \
    }                                                                                                                  \
                                                                                                                       \
    ClassName ClassName::clone() const                                                                                 \
    {                                                                                                                  \
        return ClassName{ ClassName##Impl{ *m_impl } };                                                                \
    }                                                                                                                  \
                                                                                                                       \
    ClassName::~ClassName() = default;                                                                                 \
    ClassName::ClassName(const ClassName &other) = default;                                                            \
    ClassName &ClassName::operator=(const ClassName &other) = default;                                                 \
    ClassName::ClassName(ClassName &&other) noexcept = default;                                                        \
    ClassName &ClassName::operator=(ClassName &&other) noexcept = default