<commit_before>﻿/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_SharedPtr_inl_
#define _Stroika_Foundation_Memory_SharedPtr_inl_   1


/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    <mutex>

#include    "BlockAllocated.h"

#include    "../Execution/Common.h"
#include    "../Execution/Exceptions.h"
#include    "../Execution/SpinLock.h"



namespace   Stroika {
    namespace   Foundation {
        namespace   Memory {


            namespace   Private_ {
                // OK to declare this way because we cannot have threads before main, and since declared this way till be
                // properly zero initialized
                extern  Execution::SpinLock sSharedPtrCopyLock_;
            }


            /*
             ********************************************************************************
             ************ Private_::ReferenceCounterContainerType_ **************************
             ********************************************************************************
             */
            inline      Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ ()
                : fCount (0)
                , fDeleteCounter_ (true)
            {
            }
            inline  Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ (bool deleteCounter)
                : fCount (0)
                , fDeleteCounter_ (deleteCounter)
            {
            }


            /*
             ********************************************************************************
             *************************** Private_::Envelope_ ********************************
             ********************************************************************************
             */
            namespace   Private_ {
                template    <typename   T>
                class   Envelope_ {
                private:
                    T*                              fPtr_;
                    ReferenceCounterContainerType_* fCountHolder_;
                public:
                    Envelope_ (T* ptr, ReferenceCounterContainerType_* countHolder )
                        : fPtr_ (ptr)
                        , fCountHolder_ (countHolder)
                    {
                        Require ((fPtr_ == nullptr) == (fCountHolder_ == nullptr));
                    }
#if     qStroika_Foundation_Memory_SharedPtrSupportsRValueReferences_
                    inline  Envelope_ (Envelope_&& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        from.fPtr_ = nullptr;
                        from.fCountHolder_ = nullptr;
                    }
                    template    <typename T2>
                    inline  Envelope_ (Envelope_<T2>&& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        from.fPtr_ = nullptr;
                        from.fCountHolder_ = nullptr;
                    }
#endif
                    template    <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                    }
                    template <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from, T* newP) noexcept
                :
                    fPtr_ (newP)
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        // reason for this is for dynamic cast. We allow replacing the P with a newP, but the
                        // actual ptr cannot change, and this assert check automatically converts pointers to
                        // a common base pointer type
                        Require (newP == from.GetPtr ());
                    }
                    Envelope_& operator= (const Envelope_& rhs)
                    {<commit_msg>more fixes to SharedPtr to help with qStroika_Foundation_Memory_SharedPtrSupportsRValueReferences_<commit_after>﻿/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_SharedPtr_inl_
#define _Stroika_Foundation_Memory_SharedPtr_inl_   1


/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    <mutex>

#include    "BlockAllocated.h"

#include    "../Execution/Common.h"
#include    "../Execution/Exceptions.h"
#include    "../Execution/SpinLock.h"



namespace   Stroika {
    namespace   Foundation {
        namespace   Memory {


            namespace   Private_ {
                // OK to declare this way because we cannot have threads before main, and since declared this way till be
                // properly zero initialized
                extern  Execution::SpinLock sSharedPtrCopyLock_;
            }


            /*
             ********************************************************************************
             ************ Private_::ReferenceCounterContainerType_ **************************
             ********************************************************************************
             */
            inline      Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ ()
                : fCount (0)
                , fDeleteCounter_ (true)
            {
            }
            inline  Private_::ReferenceCounterContainerType_::ReferenceCounterContainerType_ (bool deleteCounter)
                : fCount (0)
                , fDeleteCounter_ (deleteCounter)
            {
            }


            /*
             ********************************************************************************
             *************************** Private_::Envelope_ ********************************
             ********************************************************************************
             */
            namespace   Private_ {
                template    <typename   T>
                class   Envelope_ {
                private:
                    T*                              fPtr_;
                    ReferenceCounterContainerType_* fCountHolder_;
                public:
                    Envelope_ (T* ptr, ReferenceCounterContainerType_* countHolder )
                        : fPtr_ (ptr)
                        , fCountHolder_ (countHolder)
                    {
                        Require ((fPtr_ == nullptr) == (fCountHolder_ == nullptr));
                    }
#if     qStroika_Foundation_Memory_SharedPtrSupportsRValueReferences_
                    inline  Envelope_ (Envelope_&& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        from.fPtr_ = nullptr;
                        from.fCountHolder_ = nullptr;
                    }
                    template    <typename T2>
                    inline  Envelope_ (Envelope_<T2>&& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        from.fPtr_ = nullptr;
                        from.fCountHolder_ = nullptr;
                    }
#endif
                    inline  Envelope_ (const Envelope_& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                    }
                    template    <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from) noexcept
                :
                    fPtr_ (from.GetPtr ())
                    , fCountHolder_ (from.fCountHolder_)
                    {
                    }
                    template <typename T2>
                    inline  Envelope_ (const Envelope_<T2>& from, T* newP) noexcept
                :
                    fPtr_ (newP)
                    , fCountHolder_ (from.fCountHolder_)
                    {
                        // reason for this is for dynamic cast. We allow replacing the P with a newP, but the
                        // actual ptr cannot change, and this assert check automatically converts pointers to
                        // a common base pointer type
                        Require (newP == from.GetPtr ());
                    }
                    Envelope_& operator= (const Envelope_& rhs)
                    {
{'fraction_non_alphanumeric': 0.19537584922200307, 'fraction_numerical': 0.003725619110234495, 'mean_word_length': 1.4601078167115904, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '132856', 'n_tokens_mistral': 2032, 'n_tokens_neox': 1822, 'n_words': 429}