pointer_like.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // sol2
  2. // The MIT License (MIT)
  3. // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. // this software and associated documentation files (the "Software"), to deal in
  6. // the Software without restriction, including without limitation the rights to
  7. // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. // the Software, and to permit persons to whom the Software is furnished to do so,
  9. // subject to the following conditions:
  10. // The above copyright notice and this permission notice shall be included in all
  11. // copies or substantial portions of the Software.
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  14. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  16. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  17. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. #ifndef SOL_POINTER_LIKE_HPP
  19. #define SOL_POINTER_LIKE_HPP
  20. #include <sol/base_traits.hpp>
  21. #include <utility>
  22. #include <type_traits>
  23. #include <memory>
  24. namespace sol {
  25. namespace meta {
  26. namespace meta_detail {
  27. template <typename T>
  28. using is_dereferenceable_test = decltype(*std::declval<T>());
  29. template <typename T>
  30. using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*());
  31. } // namespace meta_detail
  32. template <typename T>
  33. using is_pointer_like = std::integral_constant<bool,
  34. !std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
  35. template <typename T>
  36. constexpr inline bool is_pointer_like_v = is_pointer_like<T>::value;
  37. } // namespace meta
  38. namespace detail {
  39. template <typename T>
  40. auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
  41. return std::forward<T>(item);
  42. }
  43. template <typename T>
  44. T& unwrap(std::reference_wrapper<T> arg) {
  45. return arg.get();
  46. }
  47. template <typename T>
  48. inline decltype(auto) deref(T&& item) {
  49. using Tu = meta::unqualified_t<T>;
  50. if constexpr (meta::is_pointer_like_v<Tu>) {
  51. return *std::forward<T>(item);
  52. }
  53. else {
  54. return std::forward<T>(item);
  55. }
  56. }
  57. template <typename T>
  58. inline decltype(auto) deref_move_only(T&& item) {
  59. using Tu = meta::unqualified_t<T>;
  60. if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
  61. return *std::forward<T>(item);
  62. }
  63. else {
  64. return std::forward<T>(item);
  65. }
  66. }
  67. template <typename T>
  68. inline T* ptr(T& val) {
  69. return std::addressof(val);
  70. }
  71. template <typename T>
  72. inline T* ptr(std::reference_wrapper<T> val) {
  73. return std::addressof(val.get());
  74. }
  75. template <typename T>
  76. inline T* ptr(T* val) {
  77. return val;
  78. }
  79. } // namespace detail
  80. } // namespace sol
  81. #endif // SOL_POINTER_LIKE_HPP