is_detected.hpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // Copyright Matt Borland 2021.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. //
  6. // https://en.cppreference.com/w/cpp/experimental/is_detected
  7. #ifndef BOOST_MATH_TOOLS_IS_DETECTED_HPP
  8. #define BOOST_MATH_TOOLS_IS_DETECTED_HPP
  9. #include <type_traits>
  10. namespace boost { namespace math { namespace tools {
  11. template <typename...>
  12. using void_t = void;
  13. namespace detail {
  14. template <typename Default, typename AlwaysVoid, template<typename...> class Op, typename... Args>
  15. struct detector
  16. {
  17. using value_t = std::false_type;
  18. using type = Default;
  19. };
  20. template <typename Default, template<typename...> class Op, typename... Args>
  21. struct detector<Default, void_t<Op<Args...>>, Op, Args...>
  22. {
  23. using value_t = std::true_type;
  24. using type = Op<Args...>;
  25. };
  26. } // Namespace detail
  27. // Special type to indicate detection failure
  28. struct nonesuch
  29. {
  30. nonesuch() = delete;
  31. ~nonesuch() = delete;
  32. nonesuch(const nonesuch&) = delete;
  33. void operator=(const nonesuch&) = delete;
  34. };
  35. template <template<typename...> class Op, typename... Args>
  36. using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
  37. template <template<typename...> class Op, typename... Args>
  38. using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;
  39. template <typename Default, template<typename...> class Op, typename... Args>
  40. using detected_or = detail::detector<Default, void, Op, Args...>;
  41. }}} // Namespaces boost math tools
  42. #endif // BOOST_MATH_TOOLS_IS_DETECTED_HPP