diff --git a/vowpalwabbit/serialization/include/vw/serialization/type_builder.h b/vowpalwabbit/serialization/include/vw/serialization/type_builder.h
index 9ad4547e136..59679529ab2 100644
--- a/vowpalwabbit/serialization/include/vw/serialization/type_builder.h
+++ b/vowpalwabbit/serialization/include/vw/serialization/type_builder.h
@@ -38,7 +38,6 @@ namespace typesys
if (typesys::is_instance
::value)
{
// need to pull out the inner type of the property
-
std::cout << "type: " << typeid(typename P::value_type).name() << std::endl;
// this is a scalar
@@ -129,4 +128,4 @@ namespace typesys
binding_builder(BaseT& pb) : BaseT(pb)
{}
};
-}
\ No newline at end of file
+}
diff --git a/vowpalwabbit/serialization/include/vw/serialization/type_erase.h b/vowpalwabbit/serialization/include/vw/serialization/type_erase.h
index 150a3ac93c7..523bd62b97b 100644
--- a/vowpalwabbit/serialization/include/vw/serialization/type_erase.h
+++ b/vowpalwabbit/serialization/include/vw/serialization/type_erase.h
@@ -235,9 +235,9 @@ struct ref
}
// void* ctor
- // ref(void*& r) : _r(&r)
- // {
- // }
+ ref(void* r) : _r(r)
+ {
+ }
//getter
template
@@ -409,4 +409,4 @@ struct vtype
// TODO: Do we need to implement erase(v_array<>)?
};
-}
\ No newline at end of file
+}
diff --git a/vowpalwabbit/serialization/src/autofb.cc b/vowpalwabbit/serialization/src/autofb.cc
index 921328d4ba4..498607100dd 100644
--- a/vowpalwabbit/serialization/src/autofb.cc
+++ b/vowpalwabbit/serialization/src/autofb.cc
@@ -18,6 +18,7 @@ namespace autofb
{ typeid(std::int8_t), "int8" },
{ typeid(std::int16_t), "int16" },
{ typeid(std::int32_t), "int32" },
+ { typeid(std::int64_t), "int64" },
{ typeid(std::uint8_t), "uint8" },
{ typeid(std::uint16_t), "uint16" },
{ typeid(std::uint32_t), "uint32" },
@@ -194,7 +195,8 @@ struct fbb_ReadElement_dispatcher
void operator()(const flatbuffers::Table& table, const reflection::Field& field, typesys::erased_lvalue_ref& value)
{
- dt.dispatch(value._type, table, field, value);
+ const bool dispatched = dt.dispatch(value._type, table, field, value);
+ assert(dispatched);
}
private:
diff --git a/vowpalwabbit/serialization/tests/autofb_schema_test.cc b/vowpalwabbit/serialization/tests/autofb_schema_test.cc
index 7c307b42dd0..b2700e981af 100644
--- a/vowpalwabbit/serialization/tests/autofb_schema_test.cc
+++ b/vowpalwabbit/serialization/tests/autofb_schema_test.cc
@@ -77,32 +77,127 @@ struct test_single
Prop a;
};
-TEST(Serialization, IndividualTypes)
+template
+auto test_single_type(const std::string& type_str) -> void
{
- std::string schema_str = R"(
- namespace test;
- table test_single {
- a:int32;
- }
- )";
+ std::string schema_str = "namespace test; table test_single { a:" + type_str + "; } ";
type_registry registry;
- type_descriptor td = type_builder_ex>::register_type(
+ type_descriptor td = type_builder_ex>::register_type(
registry, "test_single"
)
- .with_property, &test_single::a>("a")
+ .with_property, &test_single::a>("a")
.descriptor();
schema_builder builder("test", registry);
fbs_data fbs = builder.build_idl();
EXPECT_EQ(normalize(fbs.text_data), normalize(schema_str));
+}
+
+TEST(Serialization, IndividualType_SchemaGeneration)
+{
+ test_single_type("int8");
+ test_single_type("int16");
+ test_single_type("int32");
+ test_single_type("int64");
+ test_single_type("uint8");
+ test_single_type("uint16");
+ test_single_type("uint32");
+ test_single_type("uint64");
+ test_single_type("bool");
+ test_single_type("float");
+ test_single_type("double");
+ test_single_type("string");
+}
+
+TEST(SerializationSupport, ErasedLValueAndErasedField)
+{
+ // This is the struct we want to manipulate
+ test_single t;
+ t.a = 1000;
+ // erased ref to t.a
+ erased_lvalue_ref elv_t_a {
+ type>::erase(),
+ ref(t.a)
+ };
+
+ // erased ref to t
+ erased_lvalue_ref elv_t {
+ type>::erase(),
+ ref(t)
+ };
+
+ // set t.a using erased_lvalue_ref
+ auto& val = elv_t_a.get>();
+ assert(val.val == 1000);
+ val.val = 2000;
+ assert(t.a == 2000);
+
+ // field_ptr holds offset a given member variable for a given class
+ // In this case, we want to hold offset to 'a' for test_single
+ constexpr field_ptr, Prop> field_ptr_a {&test_single::a};
+
+ // Declare the pointer that will eventually point to t.a
+ erased_lvalue_ref* elv_field_ptr = nullptr;
+
+ // binder that can be used to bind t.a to an erased_lvalue_ptr
+ const erased_field_binder erased_field_binder_a = field_ptr_a.erase_binder();
+ assert(erased_field_binder_a.try_bind(elv_t, elv_field_ptr));
+
+ auto& val2 = elv_field_ptr->get>();
+
+ val2 = 3000;
+ assert(t.a == 3000);
+ delete elv_field_ptr;
+}
+
+TEST(SerializationSupport, FieldPtr)
+{
+ test_single t;
+
+ field_ptr_id,Prop,&test_single::a> ptr_id;
+ field_ptr, Prop> ptr = ptr_id();
+ Prop& x = ptr.bind(t);
+ x = 1000;
+ assert(t.a == 1000);
+
+ field_ptr, Prop> ptr2 {&test_single::a};
+ erased_lvalue_ref elv_t { type>::erase(), ref(t) };
+ Prop* y;
+ assert(ptr2.try_bind(elv_t,y));
+ y->val = 2000;
+ assert(t.a == 2000);
+
+ ///// Study this
+ erased_lvalue_ref* elv_ptr; // This will be a pointer to a Prop
+ erased_field_binder binder = ptr2.erase_binder(); // This is a binder for Prop
+ assert(binder.try_bind(elv_t, elv_ptr)); // This binds elv_ptr to t.a
+ elv_ptr->set(3000);
+ assert(t.a == 3000);
+
+ delete elv_ptr;
+}
+
+TEST(Serialization, IndividualType_Write_Read)
+{
+ // register with the global instance
+ auto& registry = type_registry::instance();
+ //Register type
+ type_descriptor td = type_builder_ex>::register_type(
+ registry, "test_single"
+ )
+ .with_property, &test_single::a>("a")
+ .descriptor();
+ schema_builder builder("test", registry);
// Serialize and deserialize test
// Begin serialize
schema schema_var = builder.build();
serializer serializer(schema_var);
flatbuffers::FlatBufferBuilder fbb;
- test_single t{1};
+
+ constexpr int input_val = 1791;
+ test_single t{input_val};
auto erased = type>::erase();
ref a_ref(t);
erased_lvalue_ref elv { erased, a_ref };
@@ -114,6 +209,9 @@ TEST(Serialization, IndividualTypes)
uint8_t* buf = fbb.GetBufferPointer();
size_t size = fbb.GetSize();
+ activation act = serializer.read_flatbuffer(buf, erased);
+ test_single out_struct = act.get>();
+ EXPECT_EQ(input_val, out_struct.a);
// End deserialize
}