Skip to content

Commit d4e4a67

Browse files
committed
Attempt the stronger is_standard_layout guard, isolated for CI (#21)
Adds static_assert(std::is_standard_layout<REFLECTABLE>::value, ...) immediately after the polymorphic guard, as its own commit so a CI failure on any platform isolates cleanly to this one static_assert. is_standard_layout on REFLECTABLE is only true if std::wstring and TimePoint both happen to be standard-layout on the active standard library, which is implementation-defined. Verified true here on Ubuntu/GCC/libstdc++ in both C++11 and C++20 (matching the issue's own measurement), for all four representative test records (Person, Pet, Company, DatetimeContainer). NOT verified in this environment on libc++ (macOS) or MSVC (Windows) - this sandbox can only build for Linux/GCC. If CI is green on macOS and Windows (both C++11 and C++20) for this commit, #21 is fully closed. If it fails on either, revert just this commit, keeping the polymorphic guard from the prior commit, and note here that the standard-layout assert is blocked pending #25 (moving the text representation off std::wstring). Also adds a mirroring ReflectionTest.ReflectableRecordsAreStandardLayout runtime test alongside the compile-time check. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUt3c1wdseRtRSSXfg3MCK
1 parent 8cb6120 commit d4e4a67

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

include/reflection.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,15 @@ static_assert(!std::is_polymorphic<REFLECTABLE>::value,
203203
"sqlite-reflection: reflectable records must not be polymorphic "
204204
"(no virtual functions or virtual/multiple inheritance).");
205205

206+
// Stronger guard, attempted separately from the polymorphic check above: is_standard_layout is
207+
// only true for REFLECTABLE if std::wstring and sqlite_reflection::TimePoint both happen to be
208+
// standard-layout on this standard library, which is implementation-defined and unverified here
209+
// on libc++ (macOS) / MSVC (Windows) - verified true on libstdc++ (Linux). If this line fails to
210+
// compile on any CI platform, that failure isolates to exactly this static_assert; remove it and
211+
// keep only the polymorphic guard above (see #21 and #25).
212+
static_assert(std::is_standard_layout<REFLECTABLE>::value,
213+
"sqlite-reflection: reflectable records must be standard-layout.");
214+
206215
/// Provide a static registration function for each reflectable struct
207216
static std::string CAT(Register, REFLECTABLE)() {
208217
std::string type_id = typeid(REFLECTABLE).name();

tests/reflection_test.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,14 @@ TEST(ReflectionTest, ReflectableRecordsAreNotPolymorphic) {
5151
EXPECT_FALSE(std::is_polymorphic<Company>::value);
5252
EXPECT_FALSE(std::is_polymorphic<DatetimeContainer>::value);
5353
}
54+
55+
// Mirrors the stronger is_standard_layout static_assert in include/reflection.h (attempted
56+
// separately from the polymorphic guard, since it's only verified on libstdc++/Linux so far -
57+
// see #21). If that assert is ever removed because a CI platform can't satisfy it, this test
58+
// should be removed alongside it rather than weakened to keep passing.
59+
TEST(ReflectionTest, ReflectableRecordsAreStandardLayout) {
60+
EXPECT_TRUE(std::is_standard_layout<Person>::value);
61+
EXPECT_TRUE(std::is_standard_layout<Pet>::value);
62+
EXPECT_TRUE(std::is_standard_layout<Company>::value);
63+
EXPECT_TRUE(std::is_standard_layout<DatetimeContainer>::value);
64+
}

0 commit comments

Comments
 (0)