traits.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #pragma once
  2. /*
  3. * Copyright 2018-present Facebook, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include <functional>
  18. #include <type_traits>
  19. #include <folly/experimental/pushmi/detail/functional.h>
  20. #define PUSHMI_NOEXCEPT_AUTO(...) \
  21. noexcept(noexcept(static_cast<decltype((__VA_ARGS__))>(__VA_ARGS__)))\
  22. /**/
  23. #define PUSHMI_NOEXCEPT_RETURN(...) \
  24. PUSHMI_NOEXCEPT_AUTO(__VA_ARGS__) {\
  25. return (__VA_ARGS__);\
  26. }\
  27. /**/
  28. namespace pushmi {
  29. #if __cpp_fold_expressions >= 201603
  30. template <bool... Bs>
  31. PUSHMI_INLINE_VAR constexpr bool and_v = (Bs && ...);
  32. template <bool... Bs>
  33. PUSHMI_INLINE_VAR constexpr bool or_v = (Bs || ...);
  34. template <int... Is>
  35. PUSHMI_INLINE_VAR constexpr int sum_v = (Is + ...);
  36. #else
  37. namespace detail {
  38. template <bool...>
  39. struct bools;
  40. template <std::size_t N>
  41. constexpr int sum_impl(int const (&rgi)[N], int i = 0, int state = 0) noexcept {
  42. return i == N ? state : sum_impl(rgi, i + 1, state + rgi[i]);
  43. }
  44. template <int... Is>
  45. constexpr int sum_impl() noexcept {
  46. using RGI = int[sizeof...(Is)];
  47. return sum_impl(RGI{Is...});
  48. }
  49. } // namespace detail
  50. template <bool... Bs>
  51. PUSHMI_INLINE_VAR constexpr bool and_v =
  52. PUSHMI_PP_IS_SAME(detail::bools<Bs..., true>, detail::bools<true, Bs...>);
  53. template <bool... Bs>
  54. PUSHMI_INLINE_VAR constexpr bool or_v = !PUSHMI_PP_IS_SAME(
  55. detail::bools<Bs..., false>,
  56. detail::bools<false, Bs...>);
  57. template <int... Is>
  58. PUSHMI_INLINE_VAR constexpr int sum_v = detail::sum_impl<Is...>();
  59. #endif
  60. template <class...>
  61. struct typelist;
  62. template <class...>
  63. using void_t = void;
  64. template <class T>
  65. using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
  66. PUSHMI_CONCEPT_DEF(
  67. template(class... Args)
  68. (concept True)(Args...),
  69. true
  70. );
  71. PUSHMI_CONCEPT_DEF(
  72. template(class T, template<class...> class C)
  73. (concept Valid)(T, C),
  74. True< C<T> >
  75. );
  76. PUSHMI_CONCEPT_DEF(
  77. template (class T, template<class...> class Trait, class... Args)
  78. (concept Satisfies)(T, Trait, Args...),
  79. static_cast<bool>(Trait<T>::type::value)
  80. );
  81. PUSHMI_CONCEPT_DEF(
  82. template (class T, class U)
  83. concept Same,
  84. PUSHMI_PP_IS_SAME(T, U) && PUSHMI_PP_IS_SAME(U, T)
  85. );
  86. PUSHMI_CONCEPT_DEF(
  87. template (bool...Bs)
  88. (concept And)(Bs...),
  89. and_v<Bs...>
  90. );
  91. PUSHMI_CONCEPT_DEF(
  92. template (bool...Bs)
  93. (concept Or)(Bs...),
  94. or_v<Bs...>
  95. );
  96. PUSHMI_CONCEPT_DEF(
  97. template (class T)
  98. concept Object,
  99. requires (T* p) (
  100. *p,
  101. implicitly_convertible_to<const volatile void*>(p)
  102. )
  103. );
  104. PUSHMI_CONCEPT_DEF(
  105. template (class T, class... Args)
  106. (concept Constructible)(T, Args...),
  107. PUSHMI_PP_IS_CONSTRUCTIBLE(T, Args...)
  108. );
  109. PUSHMI_CONCEPT_DEF(
  110. template (class T)
  111. concept MoveConstructible,
  112. Constructible<T, T>
  113. );
  114. PUSHMI_CONCEPT_DEF(
  115. template (class From, class To)
  116. concept ConvertibleTo,
  117. requires (From (&f)()) (
  118. static_cast<To>(f())
  119. ) && std::is_convertible<From, To>::value
  120. );
  121. PUSHMI_CONCEPT_DEF(
  122. template (class A, class B)
  123. concept DerivedFrom,
  124. __is_base_of(B, A)
  125. );
  126. PUSHMI_CONCEPT_DEF(
  127. template (class A)
  128. concept Decayed,
  129. Same<A, std::decay_t<A>>
  130. );
  131. PUSHMI_CONCEPT_DEF(
  132. template (class T, class U)
  133. concept Assignable,
  134. requires(T t, U&& u) (
  135. t = (U &&) u,
  136. requires_<Same<decltype(t = (U &&) u), T>>
  137. ) && Same<T, T&>
  138. );
  139. PUSHMI_CONCEPT_DEF(
  140. template (class T)
  141. concept EqualityComparable,
  142. requires(remove_cvref_t<T> const & t) (
  143. implicitly_convertible_to<bool>( t == t ),
  144. implicitly_convertible_to<bool>( t != t )
  145. )
  146. );
  147. PUSHMI_CONCEPT_DEF(
  148. template (class T)
  149. concept SemiMovable,
  150. Object<T> && Constructible<T, T> && ConvertibleTo<T, T>
  151. );
  152. PUSHMI_CONCEPT_DEF(
  153. template (class T)
  154. concept Movable,
  155. SemiMovable<T> && Assignable<T&, T>
  156. );
  157. PUSHMI_CONCEPT_DEF(
  158. template (class T)
  159. concept Copyable,
  160. Movable<T> &&
  161. Assignable<T&, const T&> &&
  162. ConvertibleTo<const T&, T>
  163. );
  164. PUSHMI_CONCEPT_DEF(
  165. template (class T)
  166. concept Semiregular,
  167. Copyable<T> && Constructible<T>
  168. );
  169. PUSHMI_CONCEPT_DEF(
  170. template (class T)
  171. concept Regular,
  172. Semiregular<T> && EqualityComparable<T>
  173. );
  174. namespace detail {
  175. // is_ taken from meta library
  176. template <typename, template <typename...> class>
  177. struct is_ : std::false_type {};
  178. template <typename... Ts, template <typename...> class C>
  179. struct is_<C<Ts...>, C> : std::true_type {};
  180. template <typename T, template <typename...> class C>
  181. constexpr bool is_v = is_<T, C>::value;
  182. template <bool B, class T = void>
  183. using requires_ = std::enable_if_t<B, T>;
  184. PUSHMI_INLINE_VAR constexpr struct as_const_fn {
  185. template <class T>
  186. constexpr const T& operator()(T& t) const noexcept {
  187. return t;
  188. }
  189. } const as_const{};
  190. } // namespace detail
  191. } // namespace pushmi