General Purpose library for Freestanding C++ and POSIX systems
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.

186 lines
5.4 KiB

  1. #pragma once
  2. #include <type_traits>
  3. #include "gp/algorithm/move.hpp"
  4. namespace gp {
  5. template<typename F, typename ... Args>
  6. auto bind_front(F&& func, Args&&... arg_parent)
  7. {
  8. return [=](auto&&... argv){
  9. return func(arg_parent..., argv...);
  10. };
  11. }
  12. /**
  13. **********************************************************************************************
  14. Code extrated from cppreference.com and the libc++ Library project, licensed under MIT license
  15. **********************************************************************************************
  16. **/
  17. namespace detail {
  18. template <class>
  19. constexpr bool is_reference_wrapper_v = false;
  20. template <class U>
  21. constexpr bool is_reference_wrapper_v<std::reference_wrapper<U>> = true;
  22. template <class T, class Type, class T1, class... Args>
  23. constexpr decltype(auto) INVOKE(Type T::* f, T1&& t1, Args&&... args)
  24. {
  25. if constexpr (std::is_member_function_pointer_v<decltype(f)>) {
  26. if constexpr (std::is_base_of_v<T, std::decay_t<T1>>)
  27. return (gp::forward<T1>(t1).*f)(gp::forward<Args>(args)...);
  28. else if constexpr (is_reference_wrapper_v<std::decay_t<T1>>)
  29. return (t1.get().*f)(gp::forward<Args>(args)...);
  30. else
  31. return ((*gp::forward<T1>(t1)).*f)(gp::forward<Args>(args)...);
  32. } else {
  33. static_assert(std::is_member_object_pointer_v<decltype(f)>);
  34. static_assert(sizeof...(args) == 0);
  35. if constexpr (std::is_base_of_v<T, std::decay_t<T1>>)
  36. return gp::forward<T1>(t1).*f;
  37. else if constexpr (is_reference_wrapper_v<std::decay_t<T1>>)
  38. return t1.get().*f;
  39. else
  40. return (*gp::forward<T1>(t1)).*f;
  41. }
  42. }
  43. template <class F, class... Args>
  44. constexpr decltype(auto) INVOKE(F&& f, Args&&... args)
  45. {
  46. return gp::forward<F>(f)(gp::forward<Args>(args)...);
  47. }
  48. } // namespace detail
  49. template< class F, class... Args>
  50. constexpr std::invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
  51. noexcept(std::is_nothrow_invocable_v<F, Args...>)
  52. {
  53. return detail::INVOKE(gp::forward<F>(f), gp::forward<Args>(args)...);
  54. }
  55. template< class T >
  56. struct remove_cvref {
  57. typedef std::remove_cv_t<std::remove_reference_t<T>> type;
  58. };
  59. template< class T >
  60. using remove_cvref_t = typename remove_cvref<T>::type;
  61. template< class T >
  62. T* addressof(T& arg)
  63. {
  64. return reinterpret_cast<T*>(
  65. &const_cast<char&>(
  66. reinterpret_cast<const volatile char&>(arg)));
  67. }
  68. namespace detail {
  69. template <class T> constexpr T& FUN(T& t) noexcept { return t; }
  70. template <class T> void FUN(T&&) = delete;
  71. }
  72. template <class T>
  73. class reference_wrapper {
  74. public:
  75. // types
  76. typedef T type;
  77. // construct/copy/destroy
  78. template <class U, class = decltype(
  79. detail::FUN<T>(std::declval<U>()),
  80. std::enable_if_t<!std::is_same_v<reference_wrapper, gp::remove_cvref_t<U>>>()
  81. )>
  82. constexpr reference_wrapper(U&& u) noexcept(noexcept(detail::FUN<T>(gp::forward<U>(u))))
  83. : _ptr(gp::addressof(detail::FUN<T>(gp::forward<U>(u)))) {}
  84. reference_wrapper(const reference_wrapper&) noexcept = default;
  85. // assignment
  86. reference_wrapper& operator=(const reference_wrapper& x) noexcept = default;
  87. // access
  88. constexpr operator T& () const noexcept { return *_ptr; }
  89. constexpr T& get() const noexcept { return *_ptr; }
  90. template< class... ArgTypes >
  91. constexpr std::invoke_result_t<T&, ArgTypes...>
  92. operator() ( ArgTypes&&... args ) const {
  93. return gp::invoke(get(), gp::forward<ArgTypes>(args)...);
  94. }
  95. private:
  96. T* _ptr;
  97. };
  98. // deduction guides
  99. template<class T>
  100. reference_wrapper(T&) -> reference_wrapper<T>;
  101. template<typename T>
  102. auto ref(T& vref) {
  103. return reference_wrapper<T>(vref);
  104. }
  105. template <class _DecayFunc>
  106. class __not_fn_imp {
  107. _DecayFunc __fd;
  108. public:
  109. __not_fn_imp() = delete;
  110. template <class ..._Args>
  111. auto operator()(_Args&& ...__args) &
  112. noexcept(noexcept(!gp::invoke(__fd, gp::forward<_Args>(__args)...)))
  113. -> decltype( !gp::invoke(__fd, gp::forward<_Args>(__args)...))
  114. { return !gp::invoke(__fd, gp::forward<_Args>(__args)...); }
  115. template <class ..._Args>
  116. auto operator()(_Args&& ...__args) &&
  117. noexcept(noexcept(!gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...)))
  118. -> decltype( !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...))
  119. { return !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...); }
  120. template <class ..._Args>
  121. auto operator()(_Args&& ...__args) const&
  122. noexcept(noexcept(!gp::invoke(__fd, gp::forward<_Args>(__args)...)))
  123. -> decltype( !gp::invoke(__fd, gp::forward<_Args>(__args)...))
  124. { return !gp::invoke(__fd, gp::forward<_Args>(__args)...); }
  125. template <class ..._Args>
  126. auto operator()(_Args&& ...__args) const&&
  127. noexcept(noexcept(!gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...)))
  128. -> decltype( !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...))
  129. { return !gp::invoke(gp::move(__fd), gp::forward<_Args>(__args)...); }
  130. private:
  131. template <class _RawFunc,
  132. class = std::enable_if_t<!std::is_same<std::decay_t<_RawFunc>, __not_fn_imp>::value>>
  133. explicit __not_fn_imp(_RawFunc&& __rf)
  134. : __fd(gp::forward<_RawFunc>(__rf)) {}
  135. template <class _RawFunc>
  136. friend inline __not_fn_imp<std::decay_t<_RawFunc>> not_fn(_RawFunc&&);
  137. };
  138. template <class _RawFunc>
  139. inline __not_fn_imp<std::decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) {
  140. return __not_fn_imp<std::decay_t<_RawFunc>>(gp::forward<_RawFunc>(__fn));
  141. }
  142. /**
  143. *********************************************************************************************
  144. */
  145. }