Micro template library A library for building device drivers
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.
 
 
 
 

83 lines
2.2 KiB

  1. /*!
  2. * \file sfinae.h
  3. * \brief Template meta-programming SFINAE helpers
  4. */
  5. #ifndef __utl_meta_sfinae_h__
  6. #define __utl_meta_sfinae_h__
  7. #include <utl/core/impl.h>
  8. #include <utl/meta/basic.h>
  9. #include <type_traits>
  10. /*!
  11. * \ingroup meta
  12. * \defgroup sfinae SFINAE
  13. * conditional use support header.
  14. */
  15. //! @{
  16. namespace utl {
  17. namespace meta {
  18. //! \name enable_if from STL
  19. //! @{
  20. //! enable_if, imported from stl
  21. template <bool If, typename _Tp = void> using enable_if = std::enable_if<If, _Tp>;
  22. //! alias template for enable_if
  23. template<bool If, typename _Tp = void> using enable_if_t = eval< enable_if<If, _Tp> >;
  24. //! @}
  25. //! \name when implementation
  26. //! @{
  27. namespace details {
  28. // template <typename... T>
  29. // struct dev_null { using type = dev_null; }; //< Same as typelist
  30. template <bool If> struct when_ { };
  31. template <> struct when_<true> { using type = void; };
  32. }
  33. //! Tool to enable a partial specialization only if a boolean condition is true.
  34. //! Well formed only if \p If is true
  35. template <bool If>
  36. using when = eval< details::when_<If> >;
  37. // //! Well formed only if all of \p Ifs are \c true
  38. // template <bool ...Ifs>
  39. // using when_all = details::dev_null<
  40. // when<Ifs>...
  41. // >;
  42. //! @}
  43. //! If same type resolves to _Ret, else SFINAE
  44. template <typename _T1, typename _T2, typename _Ret =_T1>
  45. using use_if_same_t = enable_if_t<
  46. same_<_T1, _T2>::value, _Ret
  47. >;
  48. //! If not same type resolves to _Ret, else SFINAE
  49. template <typename _T1, typename _T2, typename _Ret =_T1>
  50. using use_if_not_same_t = enable_if_t<
  51. !same_<_T1, _T2>::value, _Ret
  52. >;
  53. //! If any type (_T1 or _T2) type resolves to _Ret, else to SFINAE
  54. template <typename T1, typename... Ts>
  55. using use_if_any_t = enable_if_t<
  56. or_<T1, Ts...>::value, T1
  57. >;
  58. //! If both type (_T1 and _T2) type resolves to _Ret, else to SFINAE
  59. template <typename T1, typename... Ts>
  60. using use_if_all_t = enable_if_t<
  61. and_<T1, Ts...>::value, T1
  62. >;
  63. }}
  64. //! @}
  65. #endif /* __utl_meta_sfinae_h__ */