Skip to content

Commit a9f6df0

Browse files
jll63claude
andcommitted
core: declare the smart-pointer converting constructors once
The three constructors taking a smart pointer to a derived class carried two copies of their template parameter list: an unqualified one under `#ifdef __MRDOCS__`, for the reference, and the real `detail::`-qualified one. Only MrDocs ever compiles the first, so the two could drift apart without anything failing, and the reference would document a constraint the library does not have. The rules recorded in the previous commits cover this case, so state each constraint once, with SameSmartPtr and IsPolymorphic in a defaulted template parameter each. The rendered requires-clause is byte-for-byte what the duplicated declarations produced. The `#ifdef __MRDOCS__` blocks that remain remove declarations from the reference - friends, deleted overloads, the VirtualTraits blueprint - rather than restate them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 00e7fbf commit a9f6df0

2 files changed

Lines changed: 19 additions & 33 deletions

File tree

CLAUDE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,12 @@ Two rules keep the reference clean; the long-form version lives next to the macr
311311
and substitution short-circuits at the first failure, so a dependent type in a later condition
312312
(`typename Other::element_type`) is only formed once the earlier ones pass.
313313

314+
Between them these cover every constraint in the library, so **do not declare a member twice**, an
315+
unqualified copy under `#ifdef __MRDOCS__` beside the real one. Only MrDocs ever compiles that
316+
copy, so the two drift apart silently and the reference then documents a constraint the library
317+
does not have. The `#ifdef __MRDOCS__` blocks that remain remove declarations from the reference
318+
(friends, deleted overloads, the `VirtualTraits` blueprint) rather than restate them.
319+
314320
Only expressions are affected: types are printed from the AST, so the macro may appear anywhere in
315321
one (`method::operator()` takes
316322
`typename BOOST_OPENMETHOD_UNLESS_MRDOCS(detail::) StripVirtualDecorator<Parameters>::type...` and

include/boost/openmethod/core.hpp

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ class virtual_ptr<
12271227
detail::box_vptr<use_indirect_vptrs>(detail::null_vptr))),
12281228
obj(std::move(other.obj)) {
12291229
}
1230-
#ifdef __MRDOCS__
1230+
12311231
//! Construct from a (const) smart pointer to a derived class
12321232
//!
12331233
//! Set the object pointer with a copy of `other`. Set the v-table pointer
@@ -1252,26 +1252,19 @@ class virtual_ptr<
12521252
//! @li @c SmartPtr must be constructible from @c const @c Other&.
12531253
template<
12541254
class Other,
1255+
typename = std::enable_if_t<BOOST_OPENMETHOD_UNLESS_MRDOCS(
1256+
detail::) SameSmartPtr<SmartPtr, Other, Registry>>,
12551257
typename = std::enable_if_t<
1256-
SameSmartPtr<SmartPtr, Other, Registry> &&
1257-
IsPolymorphic<typename Other::element_type, Registry> &&
1258-
std::is_constructible_v<SmartPtr, const Other&>>>
1259-
#else
1260-
template<
1261-
class Other,
1262-
typename = std::enable_if_t<
1263-
detail::SameSmartPtr<SmartPtr, Other, Registry> &&
1264-
detail::IsPolymorphic<typename Other::element_type, Registry> &&
1258+
BOOST_OPENMETHOD_UNLESS_MRDOCS(detail::)
1259+
IsPolymorphic<typename Other::element_type, Registry> &&
12651260
std::is_constructible_v<SmartPtr, const Other&>>>
1266-
#endif
12671261
virtual_ptr(const Other& other)
12681262
: vp(detail::box_vptr<use_indirect_vptrs>(
12691263
other ? detail::acquire_vptr<Registry>(*other)
12701264
: detail::null_vptr)),
12711265
obj(other) {
12721266
}
12731267

1274-
#if __MRDOCS__
12751268
//! Construct from a smart pointer to a derived class
12761269
//!
12771270
//! Copy object pointer from `other` to `this`. Set the v-table pointer
@@ -1288,26 +1281,19 @@ class virtual_ptr<
12881281
//! @li @c SmartPtr must be constructible from @c Other&.
12891282
template<
12901283
class Other,
1284+
typename = std::enable_if_t<BOOST_OPENMETHOD_UNLESS_MRDOCS(
1285+
detail::) SameSmartPtr<SmartPtr, Other, Registry>>,
12911286
typename = std::enable_if_t<
1292-
SameSmartPtr<SmartPtr, Other, Registry> &&
1293-
IsPolymorphic<typename Other::element_type, Registry> &&
1294-
std::is_constructible_v<SmartPtr, Other&>>>
1295-
#else
1296-
template<
1297-
class Other,
1298-
typename = std::enable_if_t<
1299-
detail::SameSmartPtr<SmartPtr, Other, Registry> &&
1300-
detail::IsPolymorphic<typename Other::element_type, Registry> &&
1287+
BOOST_OPENMETHOD_UNLESS_MRDOCS(detail::)
1288+
IsPolymorphic<typename Other::element_type, Registry> &&
13011289
std::is_constructible_v<SmartPtr, Other&>>>
1302-
#endif
13031290
virtual_ptr(Other& other)
13041291
: vp(detail::box_vptr<use_indirect_vptrs>(
13051292
other ? detail::acquire_vptr<Registry>(*other)
13061293
: detail::null_vptr)),
13071294
obj(other) {
13081295
}
13091296

1310-
#ifdef __MRDOCS__
13111297
//! Move-construct from a smart pointer to a derived class
13121298
//!
13131299
//! Move object pointer from `other` to `this`. Set the v-table pointer
@@ -1331,18 +1317,12 @@ class virtual_ptr<
13311317
//! @li @c SmartPtr must be constructible from @c Other&&.
13321318
template<
13331319
class Other,
1320+
typename = std::enable_if_t<BOOST_OPENMETHOD_UNLESS_MRDOCS(
1321+
detail::) SameSmartPtr<SmartPtr, Other, Registry>>,
13341322
typename = std::enable_if_t<
1335-
SameSmartPtr<SmartPtr, Other, Registry> &&
1336-
IsPolymorphic<typename Other::element_type, Registry> &&
1337-
std::is_constructible_v<SmartPtr, Other&&>>>
1338-
#else
1339-
template<
1340-
class Other,
1341-
typename = std::enable_if_t<
1342-
detail::SameSmartPtr<SmartPtr, Other, Registry> &&
1343-
detail::IsPolymorphic<typename Other::element_type, Registry> &&
1323+
BOOST_OPENMETHOD_UNLESS_MRDOCS(detail::)
1324+
IsPolymorphic<typename Other::element_type, Registry> &&
13441325
std::is_constructible_v<SmartPtr, Other&&>>>
1345-
#endif
13461326
virtual_ptr(Other&& other)
13471327
: vp(detail::box_vptr<use_indirect_vptrs>(
13481328
other ? detail::acquire_vptr<Registry>(*other)

0 commit comments

Comments
 (0)