fake_object.hpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Copyright (c) 2023 Bela Schaum, X-Ryl669, Denis Mikhailov.
  2. // Copyright (c) 2024-2025 Antony Polukhin
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. // Initial implementation by Bela Schaum, https://github.com/schaumb
  7. // The way to make it union and UB free by X-Ryl669, https://github.com/X-Ryl669
  8. //
  9. #ifndef BOOST_PFR_DETAIL_FAKE_OBJECT_HPP
  10. #define BOOST_PFR_DETAIL_FAKE_OBJECT_HPP
  11. #pragma once
  12. #include <boost/pfr/detail/config.hpp>
  13. #ifdef __clang__
  14. # pragma clang diagnostic push
  15. # pragma clang diagnostic ignored "-Wundefined-internal"
  16. # pragma clang diagnostic ignored "-Wundefined-var-template"
  17. #endif
  18. namespace boost { namespace pfr { namespace detail {
  19. // This class has external linkage while T has not sure.
  20. template <class T>
  21. struct wrapper {
  22. const T value;
  23. };
  24. // This variable servers as a link-time assert.
  25. // If linker requires it, then `fake_object()` is used at runtime.
  26. template <class T>
  27. extern const wrapper<T> do_not_use_PFR_with_local_types;
  28. // For returning non default constructible types, it's exclusively used in member name retrieval.
  29. //
  30. // Neither std::declval nor boost::pfr::detail::unsafe_declval are usable there.
  31. // This takes advantage of C++20 features, while boost::pfr::detail::unsafe_declval works
  32. // with the former standards.
  33. template <class T>
  34. constexpr const T& fake_object() noexcept {
  35. return do_not_use_PFR_with_local_types<T>.value;
  36. }
  37. }}} // namespace boost::pfr::detail
  38. #ifdef __clang__
  39. # pragma clang diagnostic pop
  40. #endif
  41. #endif // BOOST_PFR_DETAIL_FAKE_OBJECT_HPP