You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 lines
1.4 KiB

  1. #pragma once
  2. #include <utility>
  3. #include <cpputils/mp/misc/when.h>
  4. #include <cpputils/mp/misc/default.h>
  5. namespace utl {
  6. namespace mp {
  7. namespace __impl /* forward declaration */
  8. {
  9. template<typename Tag>
  10. struct make_t;
  11. }
  12. template<typename Tag>
  13. constexpr __impl::make_t<Tag> make { };
  14. namespace __impl /* implementation */
  15. {
  16. template<typename T, typename = void>
  17. struct make_impl :
  18. public make_impl<T, when<true>>
  19. { };
  20. template<typename T, bool condition>
  21. struct make_impl<T, when<condition>> :
  22. public default_
  23. {
  24. template<typename... X>
  25. static constexpr auto make_helper(int, X&&... x)
  26. -> decltype(T(std::forward<X>(x)...))
  27. { return T(std::forward<X>(x)...); }
  28. template<typename... X>
  29. static constexpr auto make_helper(long, X&&... x)
  30. { static_assert((sizeof...(X), false), "there exists no constructor for the given data type"); }
  31. template <typename... X>
  32. static constexpr auto apply(X&& ...x)
  33. { return make_helper(int{}, std::forward<X>(x)...); }
  34. };
  35. template<typename T>
  36. struct make_t
  37. {
  38. template<typename... X>
  39. constexpr auto operator()(X&&... x) const noexcept
  40. { return make_impl<T>::apply(std::forward<X>(x)...); }
  41. };
  42. }
  43. }
  44. }