Micro template library A library for building device drivers
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

126 lignes
3.8 KiB

  1. /*!
  2. * \file use.h
  3. * \brief Template meta-programming SFINAE helpers
  4. *
  5. * Copyright (C) 2018 Christos Choutouridis
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation, either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef __utl_meta_use_h__
  21. #define __utl_meta_use_h__
  22. #include <utl/impl/impl.h>
  23. #include <utl/meta/logical.h>
  24. /*!
  25. * \ingroup meta
  26. * \defgroup use
  27. * conditional use support header. This is a SFINAE helper
  28. */
  29. //! @{
  30. namespace utl {
  31. /*!
  32. * void_t
  33. * Utility meta-function that maps a sequence of any types to the type void
  34. * \note The idea is:
  35. * template <typename ...>
  36. * using void_t = void;
  37. *
  38. * Until CWG 1558 (a C++14 defect), unused parameters in alias templates were not
  39. * guaranteed to ensure SFINAE and could be ignored, so earlier compilers require
  40. * a more complex definition of void_t, such as the following implementation
  41. * https://en.cppreference.com
  42. */
  43. //! @{
  44. template<typename... _Ts>
  45. struct void_t_impl {
  46. typedef void type;
  47. };
  48. //! The actual void_t type alias
  49. template<typename... _Ts>
  50. using void_t = typename void_t_impl<_Ts...>::type;
  51. //! @}
  52. //! If same type resolves to _Ret, else SFINAE
  53. //! @{
  54. template <typename _T1, typename _T2, typename _Ret =_T1>
  55. struct use_if_same_ {
  56. using type = if_t <
  57. same_<_T1, _T2>::value,
  58. _Ret
  59. >;
  60. };
  61. template <typename _T1, typename _T2, typename _Ret =_T1>
  62. using use_if_same_t = typename use_if_same_<_T1, _T2, _Ret>::type;
  63. //! @}
  64. //! If not same type resolves to _Ret, else SFINAE
  65. //! @{
  66. template <typename _T1, typename _T2, typename _Ret =_T1>
  67. struct use_if_not_same_ {
  68. using type = if_t <
  69. !same_<_T1, _T2>::value,
  70. _Ret
  71. >;
  72. };
  73. template <typename _T1, typename _T2, typename _Ret =_T1>
  74. using use_if_not_same_t = typename use_if_not_same_<_T1, _T2, _Ret>::type;
  75. //! @}
  76. //! If any type (_T1 or _T2) type resolves to _Ret, else to SFINAE
  77. //! @{
  78. template <typename _T1, typename _T2, typename _Ret =_T1>
  79. struct use_if_any_ {
  80. using type = if_t <
  81. or_<_T1, _T2>::value,
  82. _Ret
  83. >;
  84. };
  85. template <typename _T1, typename _T2, typename _Ret =_T1>
  86. using use_if_any_t = typename use_if_any_<_T1, _T2, _Ret>::type;
  87. //! @}
  88. //! If both type (_T1 and _T2) type resolves to _Ret, else to SFINAE
  89. //! @{
  90. template <typename _T1, typename _T2, typename _Ret =_T1>
  91. struct use_if_both_ {
  92. using type = if_t <
  93. and_<_T1, _T2>::value,
  94. _Ret
  95. >;
  96. };
  97. template <typename _T1, typename _T2, typename _Ret =_T1>
  98. using use_if_both_t = typename use_if_both_<_T1, _T2, _Ret>::type;
  99. //! @}
  100. //! Publicly recognized alias template for if_t
  101. template<bool _C, typename _Tp = void>
  102. using enable_if_t = typename if_<_C, _Tp>::type;
  103. //! Uniform use_ style alias template for if_t
  104. //!@{
  105. template<bool _C, typename _Tp = void>
  106. using use_if_t = typename if_<_C, _Tp>::type;
  107. //!@{
  108. }
  109. //! @}
  110. #endif /* __utl_meta_use_h__ */