<commit_before>#ifndef CWRAPPER_HPP_INCLUDED
#define CWRAPPER_HPP_INCLUDED

template<
    typename HANDLE_T,
    typename FUNCTIONS,
    typename EXCEPTION_T = std::bad_alloc>
class CWrapperCopiable
{
protected:
    HANDLE_T ptr;

public:

    explicit CWrapperCopiable(HANDLE_T ptr) :
        ptr{ptr}
    {
        if(ptr == nullptr)
            throw EXCEPTION_T{};
    }

    CWrapperCopiable(CWrapperCopiable const& other) :
        CWrapperCopiable{FUNCTIONS::copy_func(other.ptr)}
    { }

    // This one is needed to prevent variadic ctor to be called
    // when you want to copy a non-const object.
    CWrapperCopiable(CWrapperCopiable& other) :
        CWrapperCopiable{FUNCTIONS::copy_func(other.ptr)}
    { }

    template<typename... ARGS>
    explicit CWrapperCopiable(ARGS&&... args) :
        CWrapperCopiable{FUNCTIONS::ctor_func(std::forward<ARGS>(args)...)}
    { }

    CWrapperCopiable(CWrapperCopiable&& old) :
        CWrapperCopiable{old.ptr}
    {
        old.ptr = nullptr;
    }

    CWrapperCopiable& operator=(CWrapperCopiable&& old)
    {
        if(this != &old)
        {
            FUNCTIONS::dtor_func(ptr);
            ptr = old.ptr;
            old.ptr = nullptr;
        }
        return *this;
    }

    ~CWrapperCopiable()
    {
        FUNCTIONS::dtor_func(ptr);
    }

    operator HANDLE_T() const
    {
        return ptr;
    }

    HANDLE_T operator->() const
    {
        return ptr;
    }

    CWrapperCopiable& operator=(CWrapperCopiable const& other)
    {
        if(this != &other)
        {
            HANDLE_T new_ptr = FUNCTIONS::copy_func(other.ptr);
            if(new_ptr == nullptr)
                throw EXCEPTION_T{};

            FUNCTIONS::dtor_func(ptr);
            ptr = new_ptr;
        }
        return *this;
    }
};

template<
    typename HANDLE_T,
    typename FUNCTIONS,
    typename EXCEPTION_T = std::bad_alloc>
class CWrapperNonCopiable
{

protected:
    HANDLE_T ptr;

public:

    explicit CWrapperNonCopiable(HANDLE_T ptr) :
        ptr{ptr}
    {
        if(ptr == nullptr)
            throw EXCEPTION_T{};
    }

    template<typename... ARGS>
    explicit CWrapperNonCopiable(ARGS&&... args) :
        CWrapperNonCopiable{FUNCTIONS::ctor_func(std::forward<ARGS>(args)...)}
    { }

    CWrapperNonCopiable(CWrapperNonCopiable&& old) :
        CWrapperNonCopiable{old.ptr}
    {
        old.ptr = nullptr;
    }

    CWrapperNonCopiable& operator=(CWrapperNonCopiable&& old)
    {
        if(this != &old)
        {
            FUNCTIONS::dtor_func(ptr);
            ptr = old.ptr;
            old.ptr = nullptr;
        }
        return *this;
    }

    ~CWrapperNonCopiable()
    {
        FUNCTIONS::dtor_func(ptr);
    }

    operator HANDLE_T() const
    {
        return ptr;
    }

    HANDLE_T operator->() const
    {
        return ptr;
    }

    // This one is needed to prevent variadic ctor to be called
    // when you want to copy a non-const object.
    CWrapperNonCopiable(CWrapperNonCopiable& other) = delete;
    CWrapperNonCopiable(CWrapperNonCopiable const& other) = delete;
    CWrapperNonCopiable& operator=(CWrapperNonCopiable const& other) = delete;
};

template<
    typename H,
    typename F,
    typename E>
class __CWrapperHelper__
{
    template<typename T1, typename T2>
    struct EQ
    {
        static constexpr bool value = false;
    };

    template<typename T>
    struct EQ<T, T>
    {
        static constexpr bool value = true;
    };
<commit_msg>Base class for copy versions<commit_after>#ifndef CWRAPPER_HPP_INCLUDED
#define CWRAPPER_HPP_INCLUDED

enum class CWrapperType
{
    Implicit,
    Explicit,
    Get,
};

template<
    typename HANDLE_T,
    typename FUNCTIONS,
    typename EXCEPTION_T = std::bad_alloc>
class CWrapperBase
{
protected:
    HANDLE_T ptr;

public:

    explicit CWrapperBase(HANDLE_T ptr) :
        ptr{ptr}
    {
        if(ptr == nullptr)
            throw EXCEPTION_T{};
    }

    CWrapperBase(CWrapperBase const& other) :
        CWrapperBase{FUNCTIONS::copy_func(other.ptr)}
    { }

    // This one is needed to prevent variadic ctor to be called
    // when you want to copy a non-const object.
    CWrapperBase(CWrapperBase& other) :
        CWrapperBase{FUNCTIONS::copy_func(other.ptr)}
    { }

    template<typename... ARGS>
    explicit CWrapperBase(ARGS&&... args) :
        CWrapperBase{FUNCTIONS::ctor_func(std::forward<ARGS>(args)...)}
    { }

    CWrapperBase(CWrapperBase&& old) :
        CWrapperBase{old.ptr}
    {
        old.ptr = nullptr;
    }

    CWrapperBase& operator=(CWrapperBase&& old)
    {
        if(this != &old)
        {
            FUNCTIONS::dtor_func(ptr);
            ptr = old.ptr;
            old.ptr = nullptr;
        }
        return *this;
    }

    ~CWrapperBase()
    {
        FUNCTIONS::dtor_func(ptr);
    }

    operator HANDLE_T() const
    {
        return ptr;
    }

    HANDLE_T operator->() const
    {
        return ptr;
    }

    CWrapperBase& operator=(CWrapperBase const& other)
    {
        if(this != &other)
        {
            HANDLE_T new_ptr = FUNCTIONS::copy_func(other.ptr);
            if(new_ptr == nullptr)
                throw EXCEPTION_T{};

            FUNCTIONS::dtor_func(ptr);
            ptr = new_ptr;
        }
        return *this;
    }
};


template<
    typename HANDLE_T,
    typename FUNCTIONS,
    typename EXCEPTION_T = std::bad_alloc>
class CWrapperCopiable : protected CWrapperBase<HANDLE_T, FUNCTIONS, EXCEPTION_T>
{
    using base = CWrapperBase<HANDLE_T, FUNCTIONS, EXCEPTION_T>;

public:

    using base::CWrapperBase;
    using base::operator HANDLE_T;
    using base::operator->;

    CWrapperCopiable(CWrapperCopiable const& other) :
        base{FUNCTIONS::copy_func(other.ptr)}
    { }

    // This one is needed to prevent variadic ctor to be called
    // when you want to copy a non-const object.
    CWrapperCopiable(CWrapperCopiable& other) :
        base{FUNCTIONS::copy_func(other.ptr)}
    { }

    CWrapperCopiable& operator=(CWrapperCopiable const& other)
    {
        if(this != &other)
        {
            HANDLE_T new_ptr = FUNCTIONS::copy_func(other.ptr);
            if(new_ptr == nullptr)
                throw EXCEPTION_T{};

            FUNCTIONS::dtor_func(base::ptr);
            base::ptr = new_ptr;
        }
        return *this;
    }
};

template<
    typename HANDLE_T,
    typename FUNCTIONS,
    typename EXCEPTION_T = std::bad_alloc>
class CWrapperNonCopiable : protected CWrapperBase<HANDLE_T, FUNCTIONS, EXCEPTION_T>
{
    using base = CWrapperBase<HANDLE_T, FUNCTIONS, EXCEPTION_T>;

protected:
    HANDLE_T ptr;
public:

    using base::CWrapperBase;
    using base::operator HANDLE_T;
    using base::operator->;

    // This one is needed to prevent variadic ctor to be called
    // when you want to copy a non-const object.
    CWrapperNonCopiable(CWrapperNonCopiable& other) = delete;
    CWrapperNonCopiable(CWrapperNonCopiable const& other) = delete;
    CWrapperNonCopiable& operator=(CWrapperNonCopiable const& other) = delete;
};

template<
    typename H,
    typename F,
    typename E>
class __CWrapperHelper__
{
    template<typename T1, typename T2>
    struct EQ
    {
        static constexpr bool value = false;
    };

    template<typename T>
    struct EQ<T, T>
    {
        static constexpr bool value = true;
    };

{'fraction_non_alphanumeric': 0.10166031573217202, 'fraction_numerical': 0.0005443658138268917, 'mean_word_length': 2.323835368611488, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3974925', 'n_tokens_mistral': 2442, 'n_tokens_neox': 2304, 'n_words': 500}