// 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