<commit_before>
#if defined(_MSC_VER)
#pragma once
#endif

#ifndef KBASE_MEMORY_SCOPED_HANDLE_H_
#define KBASE_MEMORY_SCOPED_HANDLE_H_

#include <Windows.h>

#include <cstdio>

namespace kbase {

template<typename HandleType>
struct HandleTraits {
    typedef HandleType Handle;
};

template<>
struct HandleTraits<HANDLE> {
    typedef HANDLE Handle;

    static Handle NullHandle()
    {
        return nullptr;
    }

    static bool IsValid(Handle handle)
    {
        return handle != nullptr && handle != INVALID_HANDLE_VALUE;
    }

    static void Close(Handle handle)
    {
        CloseHandle(handle);
    }
};

template<>
struct HandleTraits<FILE*> {
    typedef FILE* Handle;

    static Handle NullHandle()
    {
        return nullptr;
    }

    static bool IsValid(Handle handle)
    {
        return handle != nullptr;
    }

    static void Close(Handle handle)
    {
        fclose(handle);
    }
};

/*
    - Dev Thoughts -

    ScopedHandle() -> auto-nullize the handle member
    explicit ScopedHandle(Handle) -> construct with a given handle value.
    ScopedHandle(Handle&&) -> move-ctor. transfer ownership.
    ~ScopedHandle() -> release handle if necessary.
    ScopedHandle& operator=(nullptr_t) -> explicit release.
    ScopedHandle& operator=(Handle&&) -> move-assign. transfer ownership.

    Release() -> explicit release.
    Reset() -> replace the handle.
    swap() -> swap handle.
    Close()

    Get()
    operator bool
    operator Handle

    -- non-member --
    std::hash<ScopedHandle>
    std::swap
*/
template<typename HandleType, typename TraitsType = HandleTraits<HandleType>>
class ScopedHandle {
public:
    typedef HandleType Handle;
    typedef TraitsType Traits;

    //ScopedHandle() {}
    //ScopedHandle(Handle);

private:
    Handle handle_;
};

}   // namespace kbase

#endif  // KBASE_MEMORY_SCOPED_HANDLE_H_<commit_msg>working on ScopeHandle<commit_after>
#if defined(_MSC_VER)
#pragma once
#endif

#ifndef KBASE_MEMORY_SCOPED_HANDLE_H_
#define KBASE_MEMORY_SCOPED_HANDLE_H_

#include <Windows.h>

#include <cstdio>

namespace kbase {

template<typename HandleType>
struct HandleTraits {
    typedef HandleType Handle;
};

template<>
struct HandleTraits<HANDLE> {
    typedef HANDLE Handle;

    static Handle NullHandle()
    {
        return nullptr;
    }

    static bool IsValid(Handle handle)
    {
        return handle != nullptr && handle != INVALID_HANDLE_VALUE;
    }

    static void Close(Handle handle)
    {
        CloseHandle(handle);
    }
};

template<>
struct HandleTraits<FILE*> {
    typedef FILE* Handle;

    static Handle NullHandle()
    {
        return nullptr;
    }

    static bool IsValid(Handle handle)
    {
        return handle != nullptr;
    }

    static void Close(Handle handle)
    {
        fclose(handle);
    }
};

/*
    - Dev Thoughts -

    ScopedHandle() -> auto-nullize the handle member
    explicit ScopedHandle(Handle) -> construct with a given handle value.
    ScopedHandle(Handle&&) -> move-ctor. transfer ownership.
    ~ScopedHandle() -> release handle if necessary.
    ScopedHandle& operator=(nullptr_t) -> explicit release.
    ScopedHandle& operator=(Handle&&) -> move-assign. transfer ownership.

    Release() -> explicit release.
    Reset() -> replace the handle.
    swap() -> swap handle.
    Close()

    Get()
    operator bool
    operator Handle

    -- non-member --
    std::hash<ScopedHandle>
    std::swap
*/
template<typename HandleType, typename TraitsType = HandleTraits<HandleType>>
class ScopedHandle {
public:
    typedef HandleType Handle;
    typedef TraitsType Traits;

    ScopedHandle()
        : handle_(Traits::NullHandle())
    {}

    explicit ScopedHandle(Handle handle)
        : handle_(handle)
    {}

    ScopedHandle(ScopedHandle&& other)
    {
        *this = std::move(other);
    }

    ~ScopedHandle()
    {
        *this = nullptr;
    }

    ScopedHandle& operator=(ScopedHandle&& rhs)
    {
        if (this != &rhs) {
            handle_ = rhs.handle_;
            rhs = nullptr;
        }

        return *this;
    }

    ScopedHandle& operator=(nullptr_t)
    {
        Close();
        return *this;
    }

    void Close()
    {
        if (Traits::IsValid(handle_)) {
            Traits::Close(handle_);
            handle_ = Traits::NullHandle();
        }
    }

    Handle Get() const
    {
        return handle_;
    }

private:
    Handle handle_;
};

}   // namespace kbase

#endif  // KBASE_MEMORY_SCOPED_HANDLE_H_
{'fraction_non_alphanumeric': 0.1062124248496994, 'fraction_numerical': 0.0, 'mean_word_length': 2.60224538893344, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 41, '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': '2201464', 'n_tokens_mistral': 1378, 'n_tokens_neox': 1341, 'n_words': 333}