#include <tuple>
#include <vector>
#include <array>
#include <cstdint>
#include <iostream>
namespace cpp98
{
namespace detail
{
template <typename T>
T declval();
}
template <typename T>
struct is_copy_assignable
{
private:
typedef char One;
typedef struct { char a[2]; } Two;
template <int N = sizeof(detail::declval<T&>() = detail::declval<T const&>())>
static One try_assign(int);
static Two try_assign(...);
public:
typedef typename std::conditional<sizeof(try_assign(0)) == sizeof(One),
std::true_type, std::false_type>::type type;
};
}
namespace cpp11
{
template <typename T>
struct is_copy_assignable
{
private:
template <typename U, typename = decltype(std::declval<T&>() = std::declval<T const&>())>
static std::true_type try_assign(U&&);
static std::false_type try_assign(...);
public:
using type = decltype(try_assign(std::declval<T>()));
};
}
namespace cpp1y
{
template <typename ... Args>
struct voider
{
typedef void type;
};
template <typename ... Args>
using void_t = typename voider<Args...>::type;
template <typename T, typename = void>
struct has_type_member : std::false_type
{};
template <typename T>
struct has_type_member<T, void_t<typename T::type>> : std::true_type
{};
template <typename T, typename = void>
struct is_copy_assignable : std::false_type
{};
template <typename T>
struct is_copy_assignable<T, void_t<decltype(std::declval<T&>() = std::declval<T const&>())>> : std::true_type
{};
}
class Foo
{
public:
Foo() {}
public:
Foo(Foo const& rhs) = delete;
Foo& operator= (Foo const& rhs) = delete;
};
int main()
{
bool result;
result = cpp98::is_copy_assignable<Foo>::type::value;
std::cout << result << std::endl;
result = cpp11::is_copy_assignable<Foo>::type::value;
std::cout << result << std::endl;
result = cpp1y::is_copy_assignable<Foo>::type::value;
std::cout << result << std::endl;
return 0;
}