diff --git a/include/boost/pfr/core.hpp b/include/boost/pfr/core.hpp index 5a8e1dfd..2ec5aa09 100644 --- a/include/boost/pfr/core.hpp +++ b/include/boost/pfr/core.hpp @@ -129,6 +129,9 @@ using tuple_element = detail::sequence_tuple::tuple_element using tuple_element_t = typename tuple_element::type; +template + requires std::is_member_object_pointer_v +constexpr auto index = detail::index_impl::value; /// \brief Creates a `std::tuple` from fields of an \aggregate `val`. /// diff --git a/include/boost/pfr/detail/core_index.hpp b/include/boost/pfr/detail/core_index.hpp new file mode 100644 index 00000000..5039258b --- /dev/null +++ b/include/boost/pfr/detail/core_index.hpp @@ -0,0 +1,56 @@ +// Copyright (c) 2024 Uy Ha +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_PFR_DETAIL_CORE_INDEX_HPP +#define BOOST_PFR_DETAIL_CORE_INDEX_HPP +#pragma once + +#include +#include + +#include + +namespace boost { +namespace pfr { +namespace detail { +template +auto class_of(TMember T::*) -> T; + +template +constexpr auto index_fn(); + +template = tuple_size_v> + requires std::is_member_object_pointer_v +struct index_impl {}; + +template + requires std::is_member_object_pointer_v +struct index_impl : decltype(index_fn()) {}; + +template +constexpr auto index_fn() { + if constexpr (index < tuple_size_v) { + using Class = decltype(class_of(ptr)); + constexpr auto pfr_address = std::addressof(boost::pfr::get(fake_object)); + constexpr auto mem_address = std::addressof(fake_object.*ptr); + + if constexpr (std::is_same_v) { + if constexpr (pfr_address == mem_address) { + return std::integral_constant{}; + } else { + return index_impl{}; + } + } else { + return index_impl{}; + } + } else { + return index_impl{}; + } +} +} // namespace pfr +} // namespace boost + +#endif // BOOST_PFR_DETAIL_CORE_INDEX_HPP