for_each_field.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright (c) 2016-2025 Antony Polukhin
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_PFR_DETAIL_FOR_EACH_FIELD_HPP
  6. #define BOOST_PFR_DETAIL_FOR_EACH_FIELD_HPP
  7. #pragma once
  8. #include <boost/pfr/detail/config.hpp>
  9. #include <boost/pfr/detail/core.hpp>
  10. #include <boost/pfr/detail/fields_count.hpp>
  11. #include <boost/pfr/detail/for_each_field_impl.hpp>
  12. #include <boost/pfr/detail/make_integer_sequence.hpp>
  13. #if !defined(BOOST_PFR_INTERFACE_UNIT)
  14. #include <type_traits> // metaprogramming stuff
  15. #include <utility> // forward_like
  16. #endif
  17. namespace boost { namespace pfr { namespace detail {
  18. template <class T, class F>
  19. constexpr void for_each_field(T&& value, F&& func) {
  20. #if BOOST_PFR_USE_CPP26
  21. using no_ref = std::remove_reference_t<T>;
  22. if constexpr (std::is_aggregate_v<no_ref> || std::is_bounded_array_v<no_ref>) {
  23. auto &&[... members] = value;
  24. ::boost::pfr::detail::for_each_field_impl(value,
  25. std::forward<F>(func),
  26. std::make_index_sequence<sizeof...(members)>{},
  27. std::is_rvalue_reference<T &&>{});
  28. } else {
  29. ::boost::pfr::detail::for_each_field_impl(value,
  30. std::forward<F>(func),
  31. std::make_index_sequence<1>{},
  32. std::is_rvalue_reference<T &&>{});
  33. }
  34. #else
  35. constexpr std::size_t fields_count_val = boost::pfr::detail::fields_count<std::remove_reference_t<T>>();
  36. ::boost::pfr::detail::for_each_field_dispatcher(
  37. value,
  38. [f = std::forward<F>(func)](auto&& t) mutable {
  39. // MSVC related workaround. Its lambdas do not capture constexprs.
  40. constexpr std::size_t fields_count_val_in_lambda
  41. = boost::pfr::detail::fields_count<std::remove_reference_t<T>>();
  42. ::boost::pfr::detail::for_each_field_impl(
  43. t,
  44. std::forward<F>(f),
  45. detail::make_index_sequence<fields_count_val_in_lambda>{},
  46. std::is_rvalue_reference<T&&>{}
  47. );
  48. },
  49. detail::make_index_sequence<fields_count_val>{}
  50. );
  51. #endif
  52. }
  53. }}} // namespace boost::pfr::detail
  54. #endif // BOOST_PFR_DETAIL_FOR_EACH_FIELD_HPP