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.

74 lines
1.8KB

  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2013-present
  4. //
  5. // Use, modification and distribution is subject to the
  6. // Boost Software License, Version 1.0. (See accompanying
  7. // file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // Project home: https://github.com/ericniebler/range-v3
  11. //
  12. #ifndef RANGES_V3_UTLITY_ADDRESSOF_HPP
  13. #define RANGES_V3_UTLITY_ADDRESSOF_HPP
  14. #include <memory>
  15. #include <type_traits>
  16. #include <concepts/concepts.hpp>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/detail/config.hpp>
  19. namespace ranges
  20. {
  21. /// \cond
  22. namespace detail
  23. {
  24. #ifdef __cpp_lib_addressof_constexpr
  25. using std::addressof;
  26. #else
  27. namespace check_addressof
  28. {
  29. inline ignore_t operator&(ignore_t)
  30. {
  31. return {};
  32. }
  33. template<typename T>
  34. auto addressof(T & t)
  35. {
  36. return &t;
  37. }
  38. } // namespace check_addressof
  39. template<typename T>
  40. constexpr bool has_bad_addressof()
  41. {
  42. return !std::is_scalar<T>::value &&
  43. !RANGES_IS_SAME(decltype(check_addressof::addressof(*(T *)nullptr)),
  44. ignore_t);
  45. }
  46. template<typename T>
  47. auto addressof(T & arg) noexcept -> CPP_ret(T *)(requires has_bad_addressof<T>())
  48. {
  49. return std::addressof(arg);
  50. }
  51. template<typename T>
  52. constexpr auto addressof(T & arg) noexcept
  53. -> CPP_ret(T *)(requires !has_bad_addressof<T>())
  54. {
  55. return &arg;
  56. }
  57. template<typename T>
  58. T const * addressof(T const &&) = delete;
  59. #endif
  60. } // namespace detail
  61. /// \endcond
  62. } // namespace ranges
  63. #endif