<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 _DECAF_LANG_POINTER_H_
#define _DECAF_LANG_POINTER_H_

#include <decaf/util/Config.h>
#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/ClassCastException.h>
#include <decaf/util/concurrent/atomic/AtomicInteger.h>
#include <decaf/util/Comparator.h>
#include <memory>
#include <algorithm>

namespace decaf {
namespace lang {

    class AtomicRefCounter {
    private:

        decaf::util::concurrent::atomic::AtomicInteger* counter;

    private:

        AtomicRefCounter& operator= ( const AtomicRefCounter& );

    public:

        AtomicRefCounter() :
            counter( new decaf::util::concurrent::atomic::AtomicInteger( 1 ) ) {}
        AtomicRefCounter( const AtomicRefCounter& other ) : counter( other.counter ) {
            this->counter->incrementAndGet();
        }

        /**
         * Swaps this instance's reference counter with the one given, this allows
         * for copy-and-swap semantics of this object.
         *
         * @param other
         *      The value to swap with this one's.
         */
        void swap( AtomicRefCounter& other ) {
            std::swap( this->counter, other.counter );
        }

        /**
         * Removes a reference to the counter Atomically and returns if the counter
         * has reached zero, once the counter hits zero, the internal counter is
         * destroyed and this instance is now considered to be unreferenced.
         *
         * @return true if the count is now zero.
         */
        bool release() {
            if( this->counter->decrementAndGet() == 0 ) {
                delete this->counter;
                return true;
            }
            return false;
        }
    };

    // Used internally in Pointer.
    struct STATIC_CAST_TOKEN {};
    struct DYNAMIC_CAST_TOKEN {};

    /**
     * Decaf's implementation of a Smart Pointer that is a template on a Type
     * and is Thread Safe if the default Reference Counter is used.  This Pointer
     * type allows for the substitution of different Reference Counter implementations
     * which provide a means of using invasive reference counting if desired using
     * a custom implementation of <code>ReferenceCounter</code>.
     * <p>
     * The Decaf smart pointer provide comparison operators for comparing Pointer
     * instances in the same manner as normal pointer, except that it does not provide
     * an overload of operators ( <, <=, >, >= ).  To allow use of a Pointer in a STL
     * container that requires it, Pointer provides an implementation of std::less.
     *
     * @since 1.0
     */
    template< typename T, typename REFCOUNTER = AtomicRefCounter >
    class Pointer : public REFCOUNTER {
    private:

        T* value;

    public:

        typedef T* PointerType;          // type returned by operator->
        typedef T& ReferenceType;        // type returned by operator*
        typedef REFCOUNTER CounterType;  // Type of the Reference Counter

    public:

        /**
         * Default Constructor
         *
         * Initialized the contained pointer to NULL, using the -> operator
         * results in an exception unless reset to contain a real value.
         */
        Pointer() : REFCOUNTER(), value( NULL ) {}

        /**
         * Explicit Constructor, creates a Pointer that contains value with a
         * single reference.  This object now has ownership until a call to release.
         *
         * @param value - instance of the type we are containing here.
         */
        explicit Pointer( const PointerType value ) : REFCOUNTER(), value( value ) {
        }

        /**
         * Copy constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter.
         */
        Pointer( const Pointer& value ) throw() : REFCOUNTER( value ), value( value.value ) {}

        /**
         * Copy constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter.
         */
        template< typename T1, typename R1 >
        Pointer( const Pointer<T1, R1>& value ) throw() : REFCOUNTER( value ), value( value.get() ) {}

        /**
         * Static Cast constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter performing a static cast on the
         * value contained in the source Pointer object.
         *
         * @param value - Pointer instance to cast to this type.
         */
        template< typename T1, typename R1 >
        Pointer( const Pointer<T1, R1>& value, const STATIC_CAST_TOKEN& ) throw() :
            REFCOUNTER( value ), value( static_cast<T*>( value.get() ) ) {
        }

        /**
         * Dynamic Cast constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter performing a dynamic cast on the
         * value contained in the source Pointer object.  If the cast fails and return NULL
         * then this method throws a ClassCastException.
         *
         * @param value - Pointer instance to cast to this type.
         * @throw ClassCastException if the dynamic cast returns NULL
         */
        template< typename T1, typename R1 >
        Pointer( const Pointer<T1, R1>& value, const DYNAMIC_CAST_TOKEN& )
            throw( decaf::lang::exceptions::ClassCastException ) :
                REFCOUNTER( value ), value( dynamic_cast<T*>( value.get() ) ) {

            if( this->value == NULL ) {
                // Remove the reference we took in the Reference Counter's ctor since we
                // didn't actually create one as the dynamic cast failed..
                this->release();
                throw decaf::lang::exceptions::ClassCastException(
                    __FILE__, __LINE__, "Failed to cast source pointer to this type." );
            }
        }

        virtual ~Pointer() throw() {
            if( this->release() == true ) {
                delete this->value;
            }
        }

        /**
         * Resets the Pointer to hold the new value.  Before the new value is stored
         * reset checks if the old value should be destroyed and if so calls delete.
         * Call reset with a value of NULL is supported and acts to set this Pointer
         * to a NULL pointer.
         *
         * @param value - The new value to contain.
         */
        void reset( T* value ) {
            Pointer( value ).swap( *this );
        }

        /**
         * Gets the real pointer that is contained within this Pointer.  This is
         * not really safe since the caller could delete or alter the pointer but
         * it mimics the STL auto_ptr and gives access in cases where the caller
         * absolutely needs the real Pointer.  Use at your own risk.
         *
         * @return the contained pointer.
         */
        PointerType get() const {
            return this->value;
        }

        /**
         * Exception Safe Swap Function
         * @param value - the value to swap with this.
         */
        void swap( Pointer& value ) throw() {
            std::swap( this->value, value.value );
            REFCOUNTER::swap( value );<commit_msg>Fixes for issues found while testing on Windows.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 _DECAF_LANG_POINTER_H_
#define _DECAF_LANG_POINTER_H_

#include <decaf/util/Config.h>
#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/lang/exceptions/ClassCastException.h>
#include <decaf/util/concurrent/atomic/AtomicInteger.h>
#include <decaf/util/Comparator.h>
#include <memory>
#include <algorithm>

namespace decaf {
namespace lang {

    class AtomicRefCounter {
    private:

        decaf::util::concurrent::atomic::AtomicInteger* counter;

    private:

        AtomicRefCounter& operator= ( const AtomicRefCounter& );

    public:

        AtomicRefCounter() :
            counter( new decaf::util::concurrent::atomic::AtomicInteger( 1 ) ) {}
        AtomicRefCounter( const AtomicRefCounter& other ) : counter( other.counter ) {
            this->counter->incrementAndGet();
        }

    protected:

        /**
         * Swaps this instance's reference counter with the one given, this allows
         * for copy-and-swap semantics of this object.
         *
         * @param other
         *      The value to swap with this one's.
         */
        void swap( AtomicRefCounter& other ) {
            std::swap( this->counter, other.counter );
        }

        /**
         * Removes a reference to the counter Atomically and returns if the counter
         * has reached zero, once the counter hits zero, the internal counter is
         * destroyed and this instance is now considered to be unreferenced.
         *
         * @return true if the count is now zero.
         */
        bool release() {
            if( this->counter->decrementAndGet() == 0 ) {
                delete this->counter;
                return true;
            }
            return false;
        }
    };

    // Used internally in Pointer.
    struct STATIC_CAST_TOKEN {};
    struct DYNAMIC_CAST_TOKEN {};

    /**
     * Decaf's implementation of a Smart Pointer that is a template on a Type
     * and is Thread Safe if the default Reference Counter is used.  This Pointer
     * type allows for the substitution of different Reference Counter implementations
     * which provide a means of using invasive reference counting if desired using
     * a custom implementation of <code>ReferenceCounter</code>.
     * <p>
     * The Decaf smart pointer provide comparison operators for comparing Pointer
     * instances in the same manner as normal pointer, except that it does not provide
     * an overload of operators ( <, <=, >, >= ).  To allow use of a Pointer in a STL
     * container that requires it, Pointer provides an implementation of std::less.
     *
     * @since 1.0
     */
    template< typename T, typename REFCOUNTER = AtomicRefCounter >
    class Pointer : public REFCOUNTER {
    private:

        T* value;

    public:

        typedef T* PointerType;          // type returned by operator->
        typedef T& ReferenceType;        // type returned by operator*
        typedef REFCOUNTER CounterType;  // Type of the Reference Counter

    public:

        /**
         * Default Constructor
         *
         * Initialized the contained pointer to NULL, using the -> operator
         * results in an exception unless reset to contain a real value.
         */
        Pointer() : REFCOUNTER(), value( NULL ) {}

        /**
         * Explicit Constructor, creates a Pointer that contains value with a
         * single reference.  This object now has ownership until a call to release.
         *
         * @param value - instance of the type we are containing here.
         */
        explicit Pointer( const PointerType value ) : REFCOUNTER(), value( value ) {
        }

        /**
         * Copy constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter.
         */
        Pointer( const Pointer& value ) throw() : REFCOUNTER( value ), value( value.value ) {}

        /**
         * Copy constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter.
         */
        template< typename T1, typename R1 >
        Pointer( const Pointer<T1, R1>& value ) throw() : REFCOUNTER( value ), value( value.get() ) {}

        /**
         * Static Cast constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter performing a static cast on the
         * value contained in the source Pointer object.
         *
         * @param value - Pointer instance to cast to this type.
         */
        template< typename T1, typename R1 >
        Pointer( const Pointer<T1, R1>& value, const STATIC_CAST_TOKEN& ) throw() :
            REFCOUNTER( value ), value( static_cast<T*>( value.get() ) ) {
        }

        /**
         * Dynamic Cast constructor. Copies the value contained in the pointer to the new
         * instance and increments the reference counter performing a dynamic cast on the
         * value contained in the source Pointer object.  If the cast fails and return NULL
         * then this method throws a ClassCastException.
         *
         * @param value - Pointer instance to cast to this type.
         * @throw ClassCastException if the dynamic cast returns NULL
         */
        template< typename T1, typename R1 >
        Pointer( const Pointer<T1, R1>& value, const DYNAMIC_CAST_TOKEN& )
            throw( decaf::lang::exceptions::ClassCastException ) :
                REFCOUNTER( value ), value( dynamic_cast<T*>( value.get() ) ) {

            if( this->value == NULL ) {
                // Remove the reference we took in the Reference Counter's ctor since we
                // didn't actually create one as the dynamic cast failed..
                this->release();
                throw decaf::lang::exceptions::ClassCastException(
                    __FILE__, __LINE__, "Failed to cast source pointer to this type." );
            }
        }

        virtual ~Pointer() throw() {
            if( REFCOUNTER::release() == true ) {
                delete this->value;
            }
        }

        /**
         * Resets the Pointer to hold the new value.  Before the new value is stored
         * reset checks if the old value should be destroyed and if so calls delete.
         * Call reset with a value of NULL is supported and acts to set this Pointer
         * to a NULL pointer.
         *
         * @param value - The new value to contain.
         */
        void reset( T* value ) {
            Pointer( value ).swap( *this );
        }

        /**
         * Releases the Pointer held and resets the internal pointer value to Null.  This method
         * is not guaranteed to be safe if the Pointer is held by more than one object or this
         * method is called from more than one thread.
         *
         * @param value - The new value to contain.
         *
         * @returns The pointer instance that was held by this Pointer object, the pointer is
         *          no longer owned by this Pointer and won't be freed when this Pointer goes
         *          out of scope.
         */
        T* release() {
            T* temp = this->value;
            this->value = NULL;
            return temp;
        }

        /**
         * Gets the real pointer that is contained within this Pointer.  This is
         * not really safe since the caller could delete or alter the pointer but
         * it mimics the STL auto_ptr and gives access in cases where the caller
         * absolutely needs the real Pointer.  Use at your own risk.
         *
         * @return the contained pointer.
         */
        PointerType get() const {
            return this->value;
        }

        /**
         * Exception Safe Swap Function
         * @param value - the value to swap with this.
         */
        void swap( Pointer& value ) throw() {
            std::swap( this->value, value.value );
            REFCOUNTER::swap( value );
{'fraction_non_alphanumeric': 0.07714116952155936, 'fraction_numerical': 0.002362669816893089, 'mean_word_length': 2.080604075691412, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 74, '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': '5439206', 'n_tokens_mistral': 4243, 'n_tokens_neox': 4081, 'n_words': 1783}