clone_ptr_private.h

Back to Cloning pointer

pastel/sys/pointer/clone_ptr/

// Description: Default cloning behaviour for ClonedPtr

#ifndef PASTELSYS_CLONE_PTR_PRIVATE_H
#define PASTELSYS_CLONE_PTR_PRIVATE_H

#include "pastel/sys/pointer/clone_ptr.h"

#include <type_traits>

#include <boost/mpl/if.hpp>

namespace Pastel
{

    namespace ClonePtr_
    {

        template<class Type>
        struct is_cloneable
        {
        private:
            typedef char (& Yes)[1];
            typedef char (& No)[2];

            template<class U, U* (U::*)() const = &U::clone> 
            struct cloneable {};

            template<class U> static Yes test( cloneable<U>* );
            template<class U> static No test(...);

        public:
            static bool const value = 
                (sizeof(test<Type>(0)) == sizeof(Yes));
        };

        class Copy_Cloner
        {
        public:
            template<class Type>
            Type* operator()(const Type& that) const 
            { 
                return new Type(that); 
            }
        };

        class Clone_Cloner
        {
        public:
            template<class Type>
            Type* operator()(const Type& that) const 
            { 
                return that.clone(); 
            }
        };

        template <typename Type>
        class Default_Cloner
        {
        public:
            typedef typename boost::mpl::if_c<
                std::is_polymorphic<Type>::value &&
                is_cloneable<Type>::value,
                Clone_Cloner, Copy_Cloner>::type type;
        };

    }

}

#endif