<commit_before>/*
Copyright (C) 2018 <NAME>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef AEONGAMES_UNIQUEANYPTR_H
#define AEONGAMES_UNIQUEANYPTR_H
#include <memory>
#include <typeinfo>

namespace AeonGames
{
    class UniqueAnyPtr
    {
    public:
        UniqueAnyPtr() noexcept = default;
        UniqueAnyPtr ( std::nullptr_t ) noexcept {};
        UniqueAnyPtr ( const UniqueAnyPtr& aUniqueResource ) = delete;
        UniqueAnyPtr& operator= ( const UniqueAnyPtr& aUniqueResource ) = delete;
        UniqueAnyPtr ( UniqueAnyPtr&& aUniqueResource ) noexcept :
            mPointer{std::move ( aUniqueResource.mPointer ) },
                 mManager{std::move ( aUniqueResource.mManager ) }
        {
            aUniqueResource.mPointer = nullptr;
            aUniqueResource.mManager = nullptr;
        }
        UniqueAnyPtr& operator= ( UniqueAnyPtr&& aUniqueResource ) noexcept
        {
            mPointer = std::move ( aUniqueResource.mPointer );
            mManager = std::move ( aUniqueResource.mManager );
            aUniqueResource.mPointer = nullptr;
            aUniqueResource.mManager = nullptr;
            return *this;
        }

        template<class T>
        UniqueAnyPtr ( std::unique_ptr<T>&& aUniquePointer ) noexcept :
            mPointer{aUniquePointer.release() },
                 mManager{Manager<T>}
        {}

        template<class T>
        UniqueAnyPtr& operator= ( std::unique_ptr<T>&& aUniquePointer ) noexcept
        {
            mPointer = aUniquePointer.release();
            mManager = Manager<T>;
            return *this;
        }

        template<class T>
        UniqueAnyPtr ( T* aPointer ) noexcept :
            mPointer{aPointer},
                 mManager{Manager<T>}
        {}

        template<class T>
        UniqueAnyPtr& operator= ( T* aPointer ) noexcept
        {
            mPointer = aPointer;
            mManager = mManager;
            return *this;
        }

        ~UniqueAnyPtr()
        {
            if ( mManager )
            {
                mManager ( mPointer );
            };
        }

        const void* GetRaw() const
        {
            return mPointer;
        }

        template<class T> T* Get() const
        {
            if ( !HasType<T>() )
            {
                throw std::runtime_error ( "Unique resource of a different type" );
            }
            return reinterpret_cast<T*> ( mPointer );
        }
        template<class T> T* Get()
        {<commit_msg>Fixed leak on UniqueAnyPtr assignment.<commit_after>/*
Copyright (C) 2018 <NAME>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef AEONGAMES_UNIQUEANYPTR_H
#define AEONGAMES_UNIQUEANYPTR_H
#include <memory>
#include <typeinfo>

namespace AeonGames
{
    class UniqueAnyPtr
    {
    public:
        /** @name Creation and Destruction. */
        /**@{*/
        UniqueAnyPtr() noexcept = default;
        UniqueAnyPtr ( std::nullptr_t ) noexcept {};
        UniqueAnyPtr ( const UniqueAnyPtr& aUniqueResource ) = delete;
        UniqueAnyPtr& operator= ( const UniqueAnyPtr& aUniqueResource ) = delete;
        UniqueAnyPtr ( UniqueAnyPtr&& aUniqueResource ) noexcept :
            mPointer{std::move ( aUniqueResource.mPointer ) },
                 mManager{std::move ( aUniqueResource.mManager ) }
        {
            aUniqueResource.mPointer = nullptr;
            aUniqueResource.mManager = nullptr;
        }

        template<class T>
        UniqueAnyPtr ( std::unique_ptr<T>&& aUniquePointer ) noexcept :
            mPointer{aUniquePointer.release() },
                 mManager{Manager<T>}
        {}
        template<class T>
        UniqueAnyPtr ( T* aPointer ) noexcept :
            mPointer{aPointer},
                 mManager{Manager<T>}
        {}

        ~UniqueAnyPtr()
        {
            if ( mManager )
            {
                mManager ( mPointer );
            };
        }
        /**@}*/

        /** @name Assignment */
        /**@{*/
        UniqueAnyPtr& operator= ( UniqueAnyPtr&& aUniqueResource ) noexcept
        {
            if ( mManager )
            {
                mManager ( mPointer );
            };
            mPointer = std::move ( aUniqueResource.mPointer );
            mManager = std::move ( aUniqueResource.mManager );
            aUniqueResource.mPointer = nullptr;
            aUniqueResource.mManager = nullptr;
            return *this;
        }

        template<class T>
        UniqueAnyPtr& operator= ( std::unique_ptr<T>&& aUniquePointer ) noexcept
        {
            if ( mManager )
            {
                mManager ( mPointer );
            };
            mPointer = aUniquePointer.release();
            mManager = Manager<T>;
            return *this;
        }

        template<class T>
        UniqueAnyPtr& operator= ( T* aPointer ) noexcept
        {
            if ( mManager )
            {
                mManager ( mPointer );
            };
            mPointer = aPointer;
            mManager = mManager;
            return *this;
        }
        /**@{*/

        const void* GetRaw() const
        {
            return mPointer;
        }

        template<class T> T* Get() const
        {
            if ( !HasType<T>() )
            {
                throw std::runtime_error ( "Unique resource of a different type" );
            }
            return reinterpret_cast<T*> ( mPointer );
        }

        template<class T> T* Get()
        {
{'fraction_non_alphanumeric': 0.09123574441493516, 'fraction_numerical': 0.002499609436025621, 'mean_word_length': 1.8377659574468086, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4206135', 'n_tokens_mistral': 1750, 'n_tokens_neox': 1673, 'n_words': 456}