Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Continuing from the An Alternative Vector

Taking a closer look at the copy assignment operator.
In the following code I am only posting the new version of the copy assignment operator all the rest of the code is unchanged.

namespace ThorsAnvil
{
    // Traits classes
    //      SimpleCopyableAssignableTraitNoThrow: 
    //      SimpleDestructableTrivialy 
    // Helper classes
    //      SimpleDestructableTrivialy
    //      SimpleCopy

    // Forward declare the vector
    template<typename T>
    class Vector;

Declarations:

    template<typename T>
    struct SimpleCopyableAssignableTraitNoThrow
    {
        static constexpr bool value = std::is_nothrow_destructible<T>::value
                                &&    std::is_nothrow_copy_assignable<T>::value;
    };
    template<typename T>
    struct SimpleDestructableTrivialy
    {
        static constexpr bool value = std::is_trivially_destructible<T>::value;
    };
    template<typename T, bool = SimpleCopyableAssignableTraitNoThrow<T>::value>
    class SimpleCopy
    {
        public:
            void simpleCopy(Vector<T>& dst, Vector<T> const& src) const;
    };
    template<typename T, bool = SimpleDestructableTrivialy<T>::value>
    class SimpleDestroy
    {
        public:
            void destroyElements(Vector<T>& obj);
    };

Updated Vector

    template<typename T>
    class Vector
    {
        // The rest (see original question for details).

        friend class SimpleCopy<T>;
        friend class SimpleDestroy<T>;
        public:
            Vector& operator=(Vector const& value) noexcept(SimpleCopyableAssignableTraitNoThrow<T>::value)
            {
                SimpleCopy<T>   copier;
                copier.simpleCopy(*this, value);
                return *this;
            }
    };

SimpleDestroy

    template<typename T>
    class SimpleDestroy<T, true>
    {
        public:
            // The elements in object are trivially destructible.
            // This means nothing is done. As an optimization we
            // don't need to do anything to the elements, just
            // reset the size
            void destroyElements(Vector<T>& obj)
            {
                obj.length  = 0;
            }
    };
    template<typename T>
    class SimpleDestroy<T, false>
    {
        public:
            // destructor is non trivial but does not throw
            void destroyElements(Vector<T>& obj)
            {
                for(int loop = 0; loop < obj.length; ++loop)
                {
                    obj.buffer[obj.length - 1 - loop].~T();
                }
                obj.length = 0;
            }
    };

SimpleCopy

    template<typename T>
    class SimpleCopy<T, true>
    {
        public:
            // Neither constructor or destructor throw.
            // So we can optimize the copy.
            void simpleCopy(Vector<T>& dst, Vector<T> const& src) const
            {
                if (&dst == &src)
                {
                    return;
                }

                // Destroy the members of the current object
                SimpleDestroy<T>    destroyer;
                destroyer.destroyElements(dst);

                // Copy from the source object to the detonation
                // thus reusing the memory underneath. It only tries
                // to reallocate if the current object needs to be
                // re-sized.
                for(auto const& value: src)
                {
                    dst.push(value);
                }
            }
    };
    template<typename T>
    class SimpleCopy<T, false>
    {
        public:
            // Constructor or Destructor may fail.
            // So use Copy & Swap idiom to handle resource
            // allocation correctly.
            void simpleCopy(Vector<T>& dst, Vector<T> const& src) const
            {
                Vector<T>     tmp(src);       // Copy
                tmp.swap(dst);                // Swap
            }
    };           

}
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.