#pragma once

#include <iostream>

struct NoTriviallyConstructible{
  NoTriviallyConstructible() = delete;
  explicit NoTriviallyConstructible(int a) {}
};

struct NoCopyConstructible {
  NoCopyConstructible() = default;
  NoCopyConstructible(const NoCopyConstructible& a) = delete;
  NoCopyConstructible(const NoCopyConstructible&& a) = delete;
};

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

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

template <class A, class B>
struct Convert {};

template <class A, class B>
struct is_customly_convertible{
 private:
  template <class C, class D>
      static decltype(std::declval<Convert<C,
      D>>().operator()(C())) detect(Convert<C, D>);
  static void detect(...);
 public:
  static constexpr bool value = std::is_same<B, decltype(
      detect(std::declval<Convert<A, B>>()))>::value;
};