File indexing completed on 2026-08-17 08:52:04
0001
0002
0003
0004
0005
0006 #ifndef BOOST_OPENMETHOD_POLICY_VPTR_VECTOR_HPP
0007 #define BOOST_OPENMETHOD_POLICY_VPTR_VECTOR_HPP
0008
0009 #include <boost/openmethod/preamble.hpp>
0010
0011 #include <variant>
0012 #include <vector>
0013
0014 namespace boost::openmethod {
0015
0016 namespace detail {
0017
0018 template<class Registry>
0019 inline std::vector<vptr_type> vptr_vector_vptrs;
0020
0021 template<class Registry>
0022 inline std::vector<const vptr_type*> vptr_vector_indirect_vptrs;
0023
0024 }
0025
0026 namespace policies {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 struct vptr_vector : vptr {
0037 public:
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 template<class Registry>
0050 struct fn {
0051 using type_hash =
0052 typename Registry::template policy<policies::type_hash>;
0053 static constexpr auto has_type_hash = !std::is_same_v<type_hash, void>;
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template<class Context, class... Options>
0066 static auto initialize(
0067 const Context& ctx, const std::tuple<Options...>& options) -> void {
0068 std::size_t size;
0069 (void)options;
0070
0071 if constexpr (has_type_hash) {
0072 auto [_, max_value] = type_hash::initialize(ctx, options);
0073 size = max_value + 1;
0074 } else {
0075 size = 0;
0076
0077 for (auto iter = ctx.classes_begin(); iter != ctx.classes_end();
0078 ++iter) {
0079 for (auto type_iter = iter->type_id_begin();
0080 type_iter != iter->type_id_end(); ++type_iter) {
0081 size = (std::max)(size, std::size_t(*type_iter));
0082 }
0083 }
0084
0085 ++size;
0086 }
0087
0088 if constexpr (Registry::has_indirect_vptr) {
0089 detail::vptr_vector_indirect_vptrs<Registry>.resize(size);
0090 } else {
0091 detail::vptr_vector_vptrs<Registry>.resize(size);
0092 }
0093
0094 for (auto iter = ctx.classes_begin(); iter != ctx.classes_end();
0095 ++iter) {
0096 for (auto type_iter = iter->type_id_begin();
0097 type_iter != iter->type_id_end(); ++type_iter) {
0098 std::size_t index;
0099
0100 if constexpr (has_type_hash) {
0101 index = type_hash::hash(*type_iter);
0102 } else {
0103 index = std::size_t(*type_iter);
0104 }
0105
0106 if constexpr (Registry::has_indirect_vptr) {
0107 detail::vptr_vector_indirect_vptrs<Registry>[index] =
0108 &iter->vptr();
0109 } else {
0110 detail::vptr_vector_vptrs<Registry>[index] =
0111 iter->vptr();
0112 }
0113 }
0114 }
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 template<class Class>
0135 static auto dynamic_vptr(const Class& arg) -> const vptr_type& {
0136 auto dynamic_type = Registry::rtti::dynamic_type(arg);
0137 std::size_t index;
0138 if constexpr (has_type_hash) {
0139 index = type_hash::hash(dynamic_type);
0140 } else {
0141 index = std::size_t(dynamic_type);
0142
0143 if constexpr (Registry::has_runtime_checks) {
0144 std::size_t max_index = 0;
0145
0146 if constexpr (Registry::has_indirect_vptr) {
0147 max_index =
0148 detail::vptr_vector_indirect_vptrs<Registry>.size();
0149 } else {
0150 max_index = detail::vptr_vector_vptrs<Registry>.size();
0151 }
0152
0153 if (index >= max_index) {
0154 if constexpr (Registry::has_error_handler) {
0155 missing_class error;
0156 error.type = dynamic_type;
0157 Registry::error_handler::error(error);
0158 }
0159
0160 abort();
0161 }
0162 }
0163 }
0164
0165 if constexpr (Registry::has_indirect_vptr) {
0166 return *detail::vptr_vector_indirect_vptrs<Registry>[index];
0167 } else {
0168 return detail::vptr_vector_vptrs<Registry>[index];
0169 }
0170 }
0171
0172
0173
0174
0175
0176
0177 template<class... Options>
0178 static auto finalize(const std::tuple<Options...>&) -> void {
0179 using namespace policies;
0180
0181 if constexpr (Registry::has_indirect_vptr) {
0182 detail::vptr_vector_indirect_vptrs<Registry>.clear();
0183 } else {
0184 detail::vptr_vector_vptrs<Registry>.clear();
0185 }
0186 };
0187 };
0188 };
0189
0190 }
0191 }
0192
0193 #endif