core_name.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright (c) 2023 Bela Schaum, X-Ryl669, Denis Mikhailov.
  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. // Initial implementation by Bela Schaum, https://github.com/schaumb
  6. // The way to make it union and UB free by X-Ryl669, https://github.com/X-Ryl669
  7. //
  8. #ifndef BOOST_PFR_CORE_NAME_HPP
  9. #define BOOST_PFR_CORE_NAME_HPP
  10. #pragma once
  11. #include <boost/pfr/detail/config.hpp>
  12. #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
  13. #include <boost/pfr/detail/core_name.hpp>
  14. #include <boost/pfr/detail/sequence_tuple.hpp>
  15. #include <boost/pfr/detail/stdarray.hpp>
  16. #include <boost/pfr/detail/make_integer_sequence.hpp>
  17. #include <boost/pfr/tuple_size.hpp>
  18. #if !defined(BOOST_PFR_INTERFACE_UNIT)
  19. #include <cstddef> // for std::size_t
  20. #endif
  21. /// \file boost/pfr/core_name.hpp
  22. /// Contains functions \forcedlink{get_name} and \forcedlink{names_as_array} to know which names each field of any \aggregate has.
  23. ///
  24. /// \fnrefl for details.
  25. ///
  26. /// \b Synopsis:
  27. namespace boost { namespace pfr {
  28. BOOST_PFR_BEGIN_MODULE_EXPORT
  29. /// \brief Returns name of a field with index `I` in \aggregate `T`.
  30. ///
  31. /// \b Example:
  32. /// \code
  33. /// struct my_struct { int i, short s; };
  34. ///
  35. /// assert(boost::pfr::get_name<0, my_struct>() == "i");
  36. /// assert(boost::pfr::get_name<1, my_struct>() == "s");
  37. /// \endcode
  38. template <std::size_t I, class T>
  39. constexpr
  40. #ifdef BOOST_PFR_DOXYGEN_INVOKED
  41. std::string_view
  42. #else
  43. auto
  44. #endif
  45. get_name() noexcept {
  46. return detail::get_name<T, I>();
  47. }
  48. // FIXME: implement this
  49. // template<class U, class T>
  50. // constexpr auto get_name() noexcept {
  51. // return detail::sequence_tuple::get_by_type_impl<U>( detail::tie_as_names_tuple<T>() );
  52. // }
  53. /// \brief Creates a `std::array` from names of fields of an \aggregate `T`.
  54. ///
  55. /// \b Example:
  56. /// \code
  57. /// struct my_struct { int i, short s; };
  58. /// std::array<std::string_view, 2> a = boost::pfr::names_as_array<my_struct>();
  59. /// assert(a[0] == "i");
  60. /// \endcode
  61. template <class T>
  62. constexpr
  63. #ifdef BOOST_PFR_DOXYGEN_INVOKED
  64. std::array<std::string_view, boost::pfr::tuple_size_v<T>>
  65. #else
  66. auto
  67. #endif
  68. names_as_array() noexcept {
  69. return detail::make_stdarray_from_tietuple(
  70. detail::tie_as_names_tuple<T>(),
  71. detail::make_index_sequence< tuple_size_v<T> >()
  72. );
  73. }
  74. /// Calls `func` for each field with its name of a `value`
  75. ///
  76. /// \param func must have one of the following signatures:
  77. /// * any_return_type func(std::string_view name, U&& field) // field of value is perfect forwarded to function
  78. /// * any_return_type func(std::string_view name, U&& field, std::size_t i)
  79. /// * any_return_type func(std::string_view name, U&& value, I i) // Here I is an `std::integral_constant<size_t, field_index>`
  80. ///
  81. /// \param value To each field of this variable will be the `func` applied.
  82. ///
  83. /// \b Example:
  84. /// \code
  85. /// struct Toto { int a; char c; };
  86. /// Toto t {5, 'c'};
  87. /// auto print = [](std::string_view name, const auto& value){ std::cout << "Name: " << name << " Value: " << value << std::endl; };
  88. /// for_each_field_with_name(t, print);
  89. /// \endcode
  90. template <class T, class F>
  91. constexpr void for_each_field_with_name(T&& value, F&& func) {
  92. return boost::pfr::detail::for_each_field_with_name(std::forward<T>(value), std::forward<F>(func));
  93. }
  94. BOOST_PFR_END_MODULE_EXPORT
  95. }} // namespace boost::pfr
  96. #endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
  97. #endif // BOOST_PFR_CORE_NAME_HPP