Skip to content

Commit a9f488f

Browse files
authored
Convert out-of-line metadata into inline metadata storage (#76)
1 parent f65a24c commit a9f488f

2 files changed

Lines changed: 50 additions & 29 deletions

File tree

include/proxy/v4/detail/facade_meta_traits.h

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -140,44 +140,18 @@ struct invoker;
140140
PRO4D_DEF_OVERLOAD_SPECIALIZATIONS(PRO4D_DEF_INVOKER)
141141
#undef PRO4D_DEF_INVOKER
142142

143-
template <class M>
144-
struct PRO4D_ENFORCE_EBO inplace_meta_storage : M {
145-
using M::M;
146-
147-
inplace_meta_storage() = default;
148-
inplace_meta_storage(const inplace_meta_storage&) = default;
149-
template <class M2>
150-
requires(std::is_nothrow_convertible_v<const M2&, const M&>)
151-
inplace_meta_storage(const inplace_meta_storage<M2>& rhs) noexcept
152-
: M(static_cast<const M&>(*rhs)) {}
153-
inplace_meta_storage& operator=(const inplace_meta_storage&) = default;
154-
template <class M2>
155-
requires(std::is_nothrow_convertible_v<const M2&, const M&>)
156-
inplace_meta_storage&
157-
operator=(const inplace_meta_storage<M2>& rhs) noexcept {
158-
static_cast<M&>(*this) = static_cast<const M&>(*rhs);
159-
return *this;
160-
}
161-
162-
const M& operator*() const noexcept { return *this; }
163-
};
164-
165143
template <class M>
166144
struct static_meta_storage {
167145
static_meta_storage() = default;
168-
template <class M2>
169-
requires(std::is_nothrow_convertible_v<const M2&, const M&>)
170-
static_meta_storage(const static_meta_storage<M2>& rhs) noexcept
171-
: ptr_(std::addressof(static_cast<const M&>(*rhs))) {}
146+
template <class P>
147+
explicit static_meta_storage(std::in_place_type_t<P>)
148+
: ptr_(std::addressof(storage<P>)) {}
172149
template <class M2>
173150
requires(std::is_nothrow_convertible_v<const M2&, const M&>)
174151
static_meta_storage& operator=(const static_meta_storage<M2>& rhs) noexcept {
175152
ptr_ = std::addressof(static_cast<const M&>(*rhs));
176153
return *this;
177154
}
178-
template <class P>
179-
explicit static_meta_storage(std::in_place_type_t<P>)
180-
: ptr_(std::addressof(storage<P>)) {}
181155
bool has_value() const noexcept { return ptr_ != nullptr; }
182156
void reset() noexcept { ptr_ = nullptr; }
183157
const M& operator*() const noexcept { return *ptr_; }
@@ -189,6 +163,27 @@ struct static_meta_storage {
189163
static inline const M storage{std::in_place_type<P>};
190164
};
191165

166+
template <class M>
167+
struct inplace_meta_storage : M {
168+
using M::M;
169+
170+
template <class M2>
171+
requires(std::is_nothrow_convertible_v<const M2&, const M&>)
172+
inplace_meta_storage&
173+
operator=(const inplace_meta_storage<M2>& rhs) noexcept {
174+
M::operator=(*rhs);
175+
return *this;
176+
}
177+
template <class M2>
178+
requires(std::is_nothrow_convertible_v<const M2&, const M&>)
179+
inplace_meta_storage& operator=(const static_meta_storage<M2>& rhs) noexcept {
180+
M::operator=(*rhs);
181+
return *this;
182+
}
183+
184+
const M& operator*() const noexcept { return *this; }
185+
};
186+
192187
} // namespace detail
193188

194189
struct compact_facade_meta_traits {

tests/proxy_lifetime_tests.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,32 @@ TEST(ProxyLifetimeTests, Test_CopySubstitution_FromNull) {
12921292
ASSERT_FALSE(p2.has_value());
12931293
}
12941294

1295+
TEST(ProxyLifetimeTests, Test_CopySubstitution_MixedMetaStorage) {
1296+
struct Super : pro::facade_builder //
1297+
::add_convention<utils::spec::FreeToString,
1298+
std::string() const> //
1299+
::support_copy<pro::constraint_level::trivial> //
1300+
::support_relocation<pro::constraint_level::trivial> //
1301+
::support_destruction<pro::constraint_level::trivial> //
1302+
::build {};
1303+
struct Derived : pro::facade_builder //
1304+
::add_facade_with_substitution<Super> //
1305+
::build {};
1306+
static_assert(
1307+
pro::detail::specialization_of<pro::compact_facade_meta_traits::storage<
1308+
pro::detail::proxy_meta<Super>>,
1309+
pro::detail::inplace_meta_storage>);
1310+
static_assert(
1311+
pro::detail::specialization_of<pro::compact_facade_meta_traits::storage<
1312+
pro::detail::proxy_meta<Derived>>,
1313+
pro::detail::static_meta_storage>);
1314+
int v = 123;
1315+
pro::proxy<Derived> p1 = &v;
1316+
pro::proxy<Super> p2 = p1;
1317+
ASSERT_EQ(ToString(*p1), "123");
1318+
ASSERT_EQ(ToString(*p2), "123");
1319+
}
1320+
12951321
TEST(ProxyLifetimeTests, Test_MoveSubstitution_FromValue) {
12961322
utils::LifetimeTracker tracker;
12971323
std::vector<utils::LifetimeOperation> expected_ops;

0 commit comments

Comments
 (0)