StdLibExtras.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #pragma once
  2. #ifdef KERNEL
  3. #include <Kernel/StdLib.h>
  4. #else
  5. #include <LibC/stdlib.h>
  6. #include <LibC/string.h>
  7. #endif
  8. #include <AK/Types.h>
  9. void* mmx_memcpy(void* to, const void* from, size_t);
  10. [[gnu::always_inline]] inline void fast_dword_copy(dword* dest, const dword* src, size_t count)
  11. {
  12. if (count >= 256) {
  13. mmx_memcpy(dest, src, count * sizeof(count));
  14. return;
  15. }
  16. asm volatile(
  17. "rep movsl\n"
  18. : "=S"(src), "=D"(dest), "=c"(count)
  19. : "S"(src), "D"(dest), "c"(count)
  20. : "memory"
  21. );
  22. }
  23. [[gnu::always_inline]] inline void fast_dword_fill(dword* dest, dword value, size_t count)
  24. {
  25. asm volatile(
  26. "rep stosl\n"
  27. : "=D"(dest), "=c"(count)
  28. : "D"(dest), "c"(count), "a"(value)
  29. : "memory"
  30. );
  31. }
  32. namespace AK {
  33. template<typename T>
  34. inline T min(const T& a, const T& b)
  35. {
  36. return a < b ? a : b;
  37. }
  38. template<typename T>
  39. inline T max(const T& a, const T& b)
  40. {
  41. return a < b ? b : a;
  42. }
  43. template<typename T, typename U>
  44. static inline T ceil_div(T a, U b)
  45. {
  46. static_assert(sizeof(T) == sizeof(U));
  47. T result = a / b;
  48. if ((a % b) != 0)
  49. ++result;
  50. return result;
  51. }
  52. #ifdef __clang__
  53. #pragma clang diagnostic push
  54. #pragma clang diagnostic ignored "-Wconsumed"
  55. #endif
  56. template <typename T>
  57. T&& move(T& arg)
  58. {
  59. return static_cast<T&&>(arg);
  60. }
  61. #ifdef __clang__
  62. #pragma clang diagnostic pop
  63. #endif
  64. template<typename T>
  65. struct Identity {
  66. typedef T Type;
  67. };
  68. template<class T>
  69. constexpr T&& forward(typename Identity<T>::Type& param)
  70. {
  71. return static_cast<T&&>(param);
  72. }
  73. template<typename T, typename U>
  74. T exchange(T& a, U&& b)
  75. {
  76. T tmp = move(a);
  77. a = move(b);
  78. return tmp;
  79. }
  80. template<typename T, typename U>
  81. void swap(T& a, U& b)
  82. {
  83. U tmp = move((U&)a);
  84. a = (T&&)move(b);
  85. b = move(tmp);
  86. }
  87. template<bool B, class T = void>
  88. struct EnableIf
  89. {
  90. };
  91. template<class T>
  92. struct EnableIf<true, T>
  93. {
  94. typedef T Type;
  95. };
  96. template<class T> struct RemoveConst { typedef T Type; };
  97. template<class T> struct RemoveConst<const T> { typedef T Type; };
  98. template<class T> struct RemoveVolatile { typedef T Type; };
  99. template<class T> struct RemoveVolatile<const T> { typedef T Type; };
  100. template<class T> struct RemoveCV {
  101. typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
  102. };
  103. template<class T, T v>
  104. struct IntegralConstant {
  105. static constexpr T value = v;
  106. typedef T ValueType;
  107. typedef IntegralConstant Type;
  108. constexpr operator ValueType() const { return value; }
  109. constexpr ValueType operator()() const { return value; }
  110. };
  111. typedef IntegralConstant<bool, false> FalseType;
  112. typedef IntegralConstant<bool, true> TrueType;
  113. template<class T>
  114. struct __IsPointerHelper : FalseType { };
  115. template<class T>
  116. struct __IsPointerHelper<T*> : TrueType { };
  117. template<class T>
  118. struct IsPointer : __IsPointerHelper<typename RemoveCV<T>::Type> { };
  119. template<class> struct IsFunction : FalseType { };
  120. template<class Ret, class... Args> struct IsFunction<Ret(Args...)> : TrueType { };
  121. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...)> : TrueType { };
  122. template<class Ret, class... Args> struct IsFunction<Ret(Args...) const> : TrueType { };
  123. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) const> : TrueType { };
  124. template<class Ret, class... Args> struct IsFunction<Ret(Args...) volatile> : TrueType { };
  125. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) volatile> : TrueType { };
  126. template<class Ret, class... Args> struct IsFunction<Ret(Args...) const volatile> : TrueType { };
  127. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) const volatile> : TrueType { };
  128. template<class Ret, class... Args> struct IsFunction<Ret(Args...) &> : TrueType { };
  129. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) &> : TrueType { };
  130. template<class Ret, class... Args> struct IsFunction<Ret(Args...) const &> : TrueType { };
  131. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) const &> : TrueType { };
  132. template<class Ret, class... Args> struct IsFunction<Ret(Args...) volatile &> : TrueType { };
  133. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) volatile &> : TrueType { };
  134. template<class Ret, class... Args> struct IsFunction<Ret(Args...) const volatile &> : TrueType { };
  135. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) const volatile &> : TrueType { };
  136. template<class Ret, class... Args> struct IsFunction<Ret(Args...) &&> : TrueType { };
  137. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) &&> : TrueType { };
  138. template<class Ret, class... Args> struct IsFunction<Ret(Args...) const &&> : TrueType { };
  139. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) const &&> : TrueType { };
  140. template<class Ret, class... Args> struct IsFunction<Ret(Args...) volatile &&> : TrueType { };
  141. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) volatile &&> : TrueType { };
  142. template<class Ret, class... Args> struct IsFunction<Ret(Args...) const volatile &&> : TrueType { };
  143. template<class Ret, class... Args> struct IsFunction<Ret(Args...,...) const volatile &&> : TrueType { };
  144. template<class T> struct IsRvalueReference : FalseType { };
  145. template<class T> struct IsRvalueReference<T&&> : TrueType { };
  146. template<class T> struct RemovePointer { typedef T Type; };
  147. template<class T> struct RemovePointer<T*> { typedef T Type; };
  148. template<class T> struct RemovePointer<T* const> { typedef T Type; };
  149. template<class T> struct RemovePointer<T* volatile> { typedef T Type; };
  150. template<class T> struct RemovePointer<T* const volatile> { typedef T Type; };
  151. template<typename T, typename U>
  152. struct IsSame {
  153. enum { value = 0 };
  154. };
  155. template<typename T>
  156. struct IsSame<T, T> {
  157. enum { value = 1 };
  158. };
  159. }
  160. using AK::min;
  161. using AK::max;
  162. using AK::move;
  163. using AK::forward;
  164. using AK::exchange;
  165. using AK::swap;
  166. using AK::ceil_div;
  167. using AK::IsSame;