mirror of
https://github.com/boostorg/pfr.git
synced 2026-01-20 04:42:22 +00:00
Compare commits
13 Commits
master
...
member_to_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f285bc9d4 | ||
|
|
f20f0b0b79 | ||
|
|
e360f0700d | ||
|
|
9cb98e103a | ||
|
|
c951f22eb7 | ||
|
|
93d02b86ce | ||
|
|
361b8e7d02 | ||
|
|
d96e25e829 | ||
|
|
e6bc1dd9f2 | ||
|
|
24cd193eee | ||
|
|
5f2aca762c | ||
|
|
18e010f989 | ||
|
|
8383f5e204 |
@@ -14,6 +14,7 @@
|
||||
#include <boost/pfr/core_name.hpp>
|
||||
#include <boost/pfr/functions_for.hpp>
|
||||
#include <boost/pfr/functors.hpp>
|
||||
#include <boost/pfr/index_of.hpp>
|
||||
#include <boost/pfr/io.hpp>
|
||||
#include <boost/pfr/io_fields.hpp>
|
||||
#include <boost/pfr/ops.hpp>
|
||||
|
||||
@@ -42,14 +42,14 @@ constexpr void for_each_field(T&& value, F&& func) {
|
||||
|
||||
::boost::pfr::detail::for_each_field_dispatcher(
|
||||
value,
|
||||
[f = std::forward<F>(func)](auto&& t) mutable {
|
||||
[&func](auto&& t) mutable {
|
||||
// MSVC related workaround. Its lambdas do not capture constexprs.
|
||||
constexpr std::size_t fields_count_val_in_lambda
|
||||
= boost::pfr::detail::fields_count<std::remove_reference_t<T>>();
|
||||
|
||||
::boost::pfr::detail::for_each_field_impl(
|
||||
t,
|
||||
std::forward<F>(f),
|
||||
std::forward<F>(func),
|
||||
detail::make_index_sequence<fields_count_val_in_lambda>{},
|
||||
std::is_rvalue_reference<T&&>{}
|
||||
);
|
||||
|
||||
76
include/boost/pfr/index_of.hpp
Normal file
76
include/boost/pfr/index_of.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// 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 <boost/pfr/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
|
||||
|
||||
#include <boost/pfr/detail/for_each_field.hpp>
|
||||
|
||||
|
||||
#if !defined(BOOST_PFR_INTERFACE_UNIT)
|
||||
#include <type_traits>
|
||||
#include <utility> // metaprogramming stuff
|
||||
#endif
|
||||
|
||||
/// \file boost/pfr/index_of.hpp
|
||||
/// \copybrief boost::pfr::index_of
|
||||
|
||||
namespace boost { namespace pfr {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename M>
|
||||
struct address_comparing_visitor {
|
||||
template <class T>
|
||||
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 <typename T, typename M>
|
||||
constexpr std::size_t index_of(M T::*mem_ptr, const T& value) noexcept {
|
||||
if (mem_ptr == nullptr) {
|
||||
return ~static_cast<std::size_t>(0);
|
||||
}
|
||||
|
||||
detail::address_comparing_visitor<M> visitor{
|
||||
std::addressof(value.*mem_ptr),
|
||||
~static_cast<std::size_t>(0)
|
||||
};
|
||||
::boost::pfr::detail::for_each_field(value, visitor);
|
||||
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
template <typename T, typename M>
|
||||
constexpr std::size_t index_of(M T::*mem_ptr) noexcept {
|
||||
constexpr T value{};
|
||||
return ::boost::pfr::index_of(mem_ptr, value);
|
||||
}
|
||||
|
||||
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
|
||||
41
test/core/run/member_to_index.cpp
Normal file
41
test/core/run/member_to_index.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/pfr/index_of.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct Sample {
|
||||
std::string x;
|
||||
std::vector<int> y;
|
||||
std::string z;
|
||||
};
|
||||
|
||||
struct TrivialSample {
|
||||
int x;
|
||||
short y;
|
||||
bool z;
|
||||
};
|
||||
|
||||
int main() {
|
||||
#if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_CPP26
|
||||
static_assert(boost::pfr::index_of(&TrivialSample::x) == 0);
|
||||
static_assert(boost::pfr::index_of(&TrivialSample::y) == 1);
|
||||
static_assert(boost::pfr::index_of(&TrivialSample::z) == 2);
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
decltype(&Sample::x) mem_ptr = nullptr;
|
||||
if (boost::pfr::index_of(mem_ptr, {}) != (std::numeric_limits<std::size_t>::max)()) return 4;
|
||||
|
||||
if (boost::pfr::index_of(&TrivialSample::x) != 0) return 11;
|
||||
if (boost::pfr::index_of(&TrivialSample::y) != 1) return 12;
|
||||
if (boost::pfr::index_of(&TrivialSample::z) != 2) return 13;
|
||||
}
|
||||
Reference in New Issue
Block a user