From e360f0700d73f697da3a22c5bab22534d9d9c8b5 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Mon, 12 Jan 2026 20:32:43 +0300 Subject: [PATCH] cleanup --- include/boost/pfr.hpp | 1 + include/boost/pfr/core.hpp | 28 ------------ include/boost/pfr/index_of.hpp | 72 +++++++++++++++++++++++++++++++ test/core/run/member_to_index.cpp | 13 +++--- 4 files changed, 81 insertions(+), 33 deletions(-) create mode 100644 include/boost/pfr/index_of.hpp diff --git a/include/boost/pfr.hpp b/include/boost/pfr.hpp index ce44725..555bdf9 100644 --- a/include/boost/pfr.hpp +++ b/include/boost/pfr.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/pfr/core.hpp b/include/boost/pfr/core.hpp index 1ba3f78..d621f27 100644 --- a/include/boost/pfr/core.hpp +++ b/include/boost/pfr/core.hpp @@ -18,11 +18,9 @@ #include #include #include -#include #include - #if !defined(BOOST_PFR_INTERFACE_UNIT) #include #include // metaprogramming stuff @@ -279,32 +277,6 @@ constexpr detail::tie_from_structure_tuple tie_from_structure(Eleme return detail::tie_from_structure_tuple(args...); } - template - struct visitor { - template - constexpr void operator()(const T&, std::size_t) {} - - constexpr void operator()(const M& field, std::size_t idx) { - const void* field_address = std::addressof(field); - if (target_address == field_address) { - result = idx; - } - } - - const void* target_address; - std::size_t result; - }; - -template -constexpr std::size_t index_of(M T::*mem_ptr) { - constexpr const T& value = boost::pfr::detail::fake_object(); - - visitor visit{std::addressof(value.*mem_ptr), boost::pfr::tuple_size_v}; - - boost::pfr::for_each_field(value, visit); - return visit.result; -} - BOOST_PFR_END_MODULE_EXPORT }} // namespace boost::pfr diff --git a/include/boost/pfr/index_of.hpp b/include/boost/pfr/index_of.hpp new file mode 100644 index 0000000..2b2a486 --- /dev/null +++ b/include/boost/pfr/index_of.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2025-2026 Antony Polukhin +// +// 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_INDEX_OF_HPP +#define BOOST_PFR_INDEX_OF_HPP +#pragma once + +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT) + +#include +#include + + +#if !defined(BOOST_PFR_INTERFACE_UNIT) +#include +#include // metaprogramming stuff +#endif + +/// \file boost/pfr/index_of.hpp +/// \copybrief boost::pfr::index_of + +namespace boost { namespace pfr { + +namespace detail { + +template +struct address_comparing_visitor { + template + constexpr void operator()(const T&, std::size_t) noexcept {} + + constexpr void operator()(const M& field, std::size_t idx) noexcept { + const void* field_address = std::addressof(field); + if (target_address == field_address) { + result = idx; + } + } + + const void* const target_address; + std::size_t result; +}; + +} + +BOOST_PFR_BEGIN_MODULE_EXPORT + +template +constexpr std::size_t index_of(M T::*mem_ptr) noexcept { + if (mem_ptr == nullptr) { + return ~static_cast(0); + } + + constexpr const T& value = boost::pfr::detail::fake_object(); + detail::address_comparing_visitor visitor{ + std::addressof(value.*mem_ptr), + ~static_cast(0) + }; + ::boost::pfr::detail::for_each_field(value, visitor); + + return visitor.result; +} + +BOOST_PFR_END_MODULE_EXPORT + +}} // namespace boost::pfr + +#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT) + +#endif // BOOST_PFR_INDEX_OF_HPP diff --git a/test/core/run/member_to_index.cpp b/test/core/run/member_to_index.cpp index f734ad9..2248821 100644 --- a/test/core/run/member_to_index.cpp +++ b/test/core/run/member_to_index.cpp @@ -3,9 +3,9 @@ // 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) -#include +#include -#include +#include #include #include @@ -21,8 +21,11 @@ int main() { static_assert(boost::pfr::index_of(&Sample::y) == 1); static_assert(boost::pfr::index_of(&Sample::z) == 2); #else - assert(boost::pfr::index_of(&Sample::x) == 0); - assert(boost::pfr::index_of(&Sample::y) == 1); - assert(boost::pfr::index_of(&Sample::z) == 2); + if (boost::pfr::index_of(&Sample::x) != 0) return 1; + if (boost::pfr::index_of(&Sample::y) != 1) return 2; + if (boost::pfr::index_of(&Sample::z) != 2) return 3; #endif + + decltype(&Sample::x) mem_ptr = nullptr; + if (boost::pfr::index_of(mem_ptr) != (std::numeric_limits::max)()) return 4; }