utility.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #ifndef ENTT_CORE_UTILITY_HPP
  2. #define ENTT_CORE_UTILITY_HPP
  3. #include <type_traits>
  4. #include <utility>
  5. namespace entt {
  6. /*! @brief Identity function object (waiting for C++20). */
  7. struct identity {
  8. /*! @brief Indicates that this is a transparent function object. */
  9. using is_transparent = void;
  10. /**
  11. * @brief Returns its argument unchanged.
  12. * @tparam Type Type of the argument.
  13. * @param value The actual argument.
  14. * @return The submitted value as-is.
  15. */
  16. template<typename Type>
  17. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  18. return std::forward<Type>(value);
  19. }
  20. };
  21. /**
  22. * @brief Constant utility to disambiguate overloaded members of a class.
  23. * @tparam Type Type of the desired overload.
  24. * @tparam Class Type of class to which the member belongs.
  25. * @param member A valid pointer to a member.
  26. * @return Pointer to the member.
  27. */
  28. template<typename Type, typename Class>
  29. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  30. return member;
  31. }
  32. /**
  33. * @brief Constant utility to disambiguate overloaded functions.
  34. * @tparam Func Function type of the desired overload.
  35. * @param func A valid pointer to a function.
  36. * @return Pointer to the function.
  37. */
  38. template<typename Func>
  39. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  40. return func;
  41. }
  42. /**
  43. * @brief Helper type for visitors.
  44. * @tparam Func Types of function objects.
  45. */
  46. template<typename... Func>
  47. struct overloaded: Func... {
  48. using Func::operator()...;
  49. };
  50. /**
  51. * @brief Deduction guide.
  52. * @tparam Func Types of function objects.
  53. */
  54. template<typename... Func>
  55. overloaded(Func...) -> overloaded<Func...>;
  56. /**
  57. * @brief Basic implementation of a y-combinator.
  58. * @tparam Func Type of a potentially recursive function.
  59. */
  60. template<typename Func>
  61. struct y_combinator {
  62. /**
  63. * @brief Constructs a y-combinator from a given function.
  64. * @param recursive A potentially recursive function.
  65. */
  66. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  67. : func{std::move(recursive)} {}
  68. /**
  69. * @brief Invokes a y-combinator and therefore its underlying function.
  70. * @tparam Args Types of arguments to use to invoke the underlying function.
  71. * @param args Parameters to use to invoke the underlying function.
  72. * @return Return value of the underlying function, if any.
  73. */
  74. template<typename... Args>
  75. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  76. return func(*this, std::forward<Args>(args)...);
  77. }
  78. /*! @copydoc operator()() */
  79. template<typename... Args>
  80. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  81. return func(*this, std::forward<Args>(args)...);
  82. }
  83. private:
  84. Func func;
  85. };
  86. } // namespace entt
  87. #endif