编译过

This commit is contained in:
2026-08-20 14:45:12 +08:00
parent f379907f1b
commit 44af33bee6
14 changed files with 991 additions and 293 deletions
+95
View File
@@ -0,0 +1,95 @@
#include "double_buffer/object.hpp"
#include <gtest/gtest.h>
namespace {
struct Object_State_Tag {};
struct Test_Object : double_buffer::Impl<Test_Object, double_buffer::Root, double_buffer::State_Type<Object_State_Tag>> {
struct Prop : Prev_Prop {
int first{};
int second{};
};
struct State : Prev_State<Object_State_Tag> {
int first{};
int second{};
bool operator==(const State&) const = default;
};
struct Private : Prev_Private {};
};
using Object = double_buffer::Attach_Object<Test_Object>;
struct Derived_State_Tag {};
struct Derived_Object : double_buffer::Impl<Derived_Object, Test_Object, double_buffer::State_Type<Derived_State_Tag>> {
struct Prop : Prev_Prop {};
struct State : Prev_State<Derived_State_Tag> {
int derived{};
bool operator==(const State&) const = default;
};
struct Private : Prev_Private {};
};
using Derived = double_buffer::Attach_Object<Derived_Object>;
}
TEST(object_buffer, state_moves_inward_and_keeps_incremental_baseline) {
Object object;
object.update_state<&Test_Object::State::first>(3);
object.exchange();
EXPECT_EQ(object.d.state.current->first, 3);
EXPECT_EQ(object.d.state.pending->first, 3);
object.update_state<&Test_Object::State::second>(5);
object.exchange();
EXPECT_EQ(object.d.state.current->first, 3);
EXPECT_EQ(object.d.state.current->second, 5);
}
TEST(object_buffer, prop_moves_outward_and_keeps_incremental_baseline) {
Object object;
object.set(&Test_Object::Prop::first, 17);
EXPECT_EQ(object.d.current->first, 17);
EXPECT_EQ(object.d.pending->first, 0);
object.exchange();
EXPECT_EQ(object.d.pending->first, 17);
EXPECT_EQ(object.d.current->first, 17);
object.set(&Test_Object::Prop::second, 19);
object.exchange();
EXPECT_EQ(object.d.pending->first, 17);
EXPECT_EQ(object.d.pending->second, 19);
}
TEST(state_tag, callback_publishes_only_requested_layer) {
Object object;
int calls = 0;
object.set_state_callback<Object_State_Tag>(
[&](const auto& state) {
++calls;
EXPECT_EQ(state.first, 23);
}
);
object.update_state<&Test_Object::State::first>(23);
object.exchange();
EXPECT_EQ(calls, 0);
object.notify_state<Object_State_Tag>();
EXPECT_EQ(calls, 1);
}
static_assert(requires(Object& object) {
object.template access_state<Object_State_Tag>([](const auto&) {});
});
struct Missing_State_Tag {};
static_assert(!double_buffer::detail::State_Tag_In<Missing_State_Tag, Object::States>);
TEST(state_tag, inherited_tags_remain_independently_addressable) {
Derived object;
int base_calls = 0;
int derived_calls = 0;
object.set_state_callback<Object_State_Tag>([&](const auto&) { ++base_calls; });
object.set_state_callback<Derived_State_Tag>([&](const auto&) { ++derived_calls; });
object.notify_state<Object_State_Tag>();
EXPECT_EQ(base_calls, 1);
EXPECT_EQ(derived_calls, 0);
object.notify_state<Derived_State_Tag>();
EXPECT_EQ(base_calls, 1);
EXPECT_EQ(derived_calls, 1);
}
static_assert(double_buffer::detail::State_Tag_In<double_buffer::Root_State_Tag, Derived::States>);
static_assert(double_buffer::detail::State_Tag_In<Object_State_Tag, Derived::States>);
static_assert(double_buffer::detail::State_Tag_In<Derived_State_Tag, Derived::States>);
TEST(state_tag, state_chain_keeps_default_equality_usable) {
Test_Object::State first;
Test_Object::State second;
EXPECT_TRUE(first == second);
second.first = 1;
EXPECT_FALSE(first == second);
}