#pragma once

struct NoTriviallyConstructible {
 public:
    NoTriviallyConstructible() = delete;
};

struct NoCopyConstructible {
 public:
    NoCopyConstructible(const  NoCopyConstructible&) = delete;
    NoCopyConstructible& operator=(const  NoCopyConstructible&) = delete;
};

template <>
struct Convert<NoTriviallyConstructible, int> {
    int operator()(const int& a) {
        return a;
    }
};

template <>
struct Convert<NoCopyConstructible, NoTriviallyConstructible> {
    int operator()(const int& a) {
        return a;
    }
};

template<typename T1, typename T2>
static constexpr bool is_convert() {
    return true;
}


template<typename T, typename Ti>
struct is_customly_convertible {
    static void detect(...);

    template<typename T1, typename T2>
    static decltype(std::declval<Convert<T1, T2>>().operator()(0), bool())
        detect(const Convert<T1, T2>&);

    template<typename T1, typename T2>
    static decltype(std::declval<Convert<T1, T2>>().operator()({ 0, 0 }),
        bool())
        detect(const Convert<T1, T2>&);

    static constexpr bool value = !std::is_same<void,
        decltype(detect(std::declval<Convert<T, Ti>>()))>::value;
};