#include <iostream>
#include <type_traits>
#include <tuple>

namespace std {

template<typename T>
struct remove_cvref {
  using type = std::remove_cv_t<std::remove_reference_t<T>>;
};

template<typename T>
using remove_cvref_t = typename remove_cvref<T>::type;

}

template<typename T, template<typename...> typename U>
struct is_derived_from_template {
  template<typename... Ts>
  static constexpr std::true_type f(U<Ts...>);
  static constexpr std::false_type f(...);
  static constexpr bool value{
      decltype(f(std::declval<std::remove_cvref_t<T>>()))::value};
};

template<typename... Ts>
struct S : std::tuple<Ts...> {
  S() = default;
};

int main() {

  S<> s0;
  S<int, double> s1;
  S<std::tuple<>> s2;
  

  std::cout << is_derived_from_template<decltype(s0), std::tuple>::value << "\n";
  std::cout << is_derived_from_template<decltype(s1), std::tuple>::value << "\n";
  std::cout << is_derived_from_template<decltype(s2), std::tuple>::value << "\n";
  
  return 0;
}