7 #include "flatbuffers/flatbuffers.h"
8 #include "monster_test_generated.h"
9 #include "test_assert.h"
11 using MyGame::Example::Color;
12 using MyGame::Example::Monster;
14 namespace flatbuffers {
18 } // namespace flatbuffers
20 template<class T, class U> struct is_same { static const bool value = false; };
22 template<class T> struct is_same<T, T> { static const bool value = true; };
24 extern const std::string m1_name;
25 extern const Color m1_color;
26 extern const std::string m2_name;
27 extern const Color m2_color;
29 flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder);
30 flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder);
32 uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
35 void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf);
36 void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf);
38 bool verify(const flatbuffers::DetachedBuffer &buf,
39 const std::string &expected_name, Color color);
40 bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
43 bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
44 const std::string &expected_name, Color color);
45 bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
46 const std::string &expected_name, Color color);
49 #if !defined(FLATBUFFERS_CPP98_STL)
51 // Invokes this function when testing the following Builder types
52 // FlatBufferBuilder, TestHeapBuilder, and GrpcLikeMessageBuilder
53 template<class Builder>
54 void builder_move_assign_after_releaseraw_test(Builder b1) {
55 auto root_offset1 = populate1(b1);
56 b1.Finish(root_offset1);
58 std::shared_ptr<uint8_t> raw(
59 b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
60 flatbuffers::DefaultAllocator::dealloc(ptr, size);
63 auto root_offset2 = populate2(src);
64 src.Finish(root_offset2);
65 auto src_size = src.GetSize();
66 // Move into a released builder.
68 TEST_EQ_FUNC(b1.GetSize(), src_size);
69 TEST_ASSERT_FUNC(release_n_verify(b1, m2_name, m2_color));
70 TEST_EQ_FUNC(src.GetSize(), 0);
73 #endif // !defined(FLATBUFFERS_CPP98_STL)
76 void builder_move_assign_after_releaseraw_test(
77 flatbuffers::grpc::MessageBuilder b1);
79 template<class DestBuilder, class SrcBuilder = DestBuilder>
82 #if !defined(FLATBUFFERS_CPP98_STL)
84 static void empty_builder_movector_test() {
86 size_t src_size = src.GetSize();
87 DestBuilder dst(std::move(src));
88 size_t dst_size = dst.GetSize();
89 TEST_EQ_FUNC(src_size, 0);
90 TEST_EQ_FUNC(src_size, dst_size);
93 static void nonempty_builder_movector_test() {
96 size_t src_size = src.GetSize();
97 DestBuilder dst(std::move(src));
98 TEST_EQ_FUNC(src_size, dst.GetSize());
99 TEST_EQ_FUNC(src.GetSize(), 0);
102 static void builder_movector_before_finish_test() {
104 auto root_offset1 = populate1(src);
105 DestBuilder dst(std::move(src));
106 dst.Finish(root_offset1);
107 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
108 TEST_EQ_FUNC(src.GetSize(), 0);
111 static void builder_movector_after_finish_test() {
113 auto root_offset1 = populate1(src);
114 src.Finish(root_offset1);
115 auto src_size = src.GetSize();
116 DestBuilder dst(std::move(src));
117 TEST_EQ_FUNC(dst.GetSize(), src_size);
118 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
119 TEST_EQ_FUNC(src.GetSize(), 0);
122 static void builder_move_assign_before_finish_test() {
124 auto root_offset1 = populate1(src);
127 dst = std::move(src);
128 dst.Finish(root_offset1);
129 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
130 TEST_EQ_FUNC(src.GetSize(), 0);
133 static void builder_move_assign_after_finish_test() {
135 auto root_offset1 = populate1(src);
136 src.Finish(root_offset1);
137 auto src_size = src.GetSize();
139 auto root_offset2 = populate2(dst);
140 dst.Finish(root_offset2);
141 dst = std::move(src);
142 TEST_EQ_FUNC(dst.GetSize(), src_size);
143 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
144 TEST_EQ_FUNC(src.GetSize(), 0);
147 static void builder_move_assign_after_release_test() {
149 auto root_offset1 = populate1(dst);
150 dst.Finish(root_offset1);
152 flatbuffers::DetachedBuffer dst_detached = dst.Release();
153 // detached buffer is deleted
156 auto root_offset2 = populate2(src);
157 src.Finish(root_offset2);
158 auto src_size = src.GetSize();
159 // Move into a released builder.
160 dst = std::move(src);
161 TEST_EQ_FUNC(dst.GetSize(), src_size);
162 TEST_ASSERT_FUNC(release_n_verify(dst, m2_name, m2_color));
163 TEST_EQ_FUNC(src.GetSize(), 0);
166 #endif // !defined(FLATBUFFERS_CPP98_STL)
169 static void builder_swap_before_finish_test(
170 bool run = is_same<DestBuilder, SrcBuilder>::value) {
171 /// Swap is allowed only when lhs and rhs are the same concrete type.
174 auto root_offset1 = populate1(src);
175 auto size1 = src.GetSize();
177 auto root_offset2 = populate2(dst);
178 auto size2 = dst.GetSize();
180 src.Finish(root_offset2);
181 dst.Finish(root_offset1);
182 TEST_EQ_FUNC(src.GetSize() > size2, true);
183 TEST_EQ_FUNC(dst.GetSize() > size1, true);
184 TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
185 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
189 static void builder_swap_after_finish_test(
190 bool run = is_same<DestBuilder, SrcBuilder>::value) {
191 /// Swap is allowed only when lhs and rhs are the same concrete type.
194 auto root_offset1 = populate1(src);
195 src.Finish(root_offset1);
196 auto size1 = src.GetSize();
198 auto root_offset2 = populate2(dst);
199 dst.Finish(root_offset2);
200 auto size2 = dst.GetSize();
202 TEST_EQ_FUNC(src.GetSize(), size2);
203 TEST_EQ_FUNC(dst.GetSize(), size1);
204 TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
205 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
209 static void all_tests() {
211 #if !defined(FLATBUFFERS_CPP98_STL)
213 empty_builder_movector_test();
214 nonempty_builder_movector_test();
215 builder_movector_before_finish_test();
216 builder_movector_after_finish_test();
217 builder_move_assign_before_finish_test();
218 builder_move_assign_after_finish_test();
219 builder_move_assign_after_release_test();
220 builder_move_assign_after_releaseraw_test(DestBuilder());
222 #endif // !defined(FLATBUFFERS_CPP98_STL)
224 builder_swap_before_finish_test();
225 builder_swap_after_finish_test();
229 enum BuilderReuseTestSelector {
230 REUSABLE_AFTER_RELEASE = 1,
231 REUSABLE_AFTER_RELEASE_RAW = 2,
232 REUSABLE_AFTER_RELEASE_MESSAGE = 3,
233 REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN = 4,
234 REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN = 5,
235 REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN = 6
238 typedef std::set<BuilderReuseTestSelector> TestSelector;
240 template<class DestBuilder, class SrcBuilder> struct BuilderReuseTests {
241 static void builder_reusable_after_release_test(TestSelector selector) {
242 if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
245 std::vector<flatbuffers::DetachedBuffer> buffers;
246 for (int i = 0; i < 5; ++i) {
247 auto root_offset1 = populate1(fbb);
248 fbb.Finish(root_offset1);
249 buffers.push_back(fbb.Release());
250 TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
254 static void builder_reusable_after_releaseraw_test(TestSelector selector) {
255 if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
258 for (int i = 0; i < 5; ++i) {
259 auto root_offset1 = populate1(fbb);
260 fbb.Finish(root_offset1);
262 uint8_t *buf = release_raw_base(fbb, size, offset);
263 TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
269 #if !defined(FLATBUFFERS_CPP98_STL)
271 static void builder_reusable_after_release_and_move_assign_test(
272 TestSelector selector) {
273 if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
276 std::vector<flatbuffers::DetachedBuffer> buffers;
277 for (int i = 0; i < 5; ++i) {
278 auto root_offset1 = populate1(dst);
279 dst.Finish(root_offset1);
280 buffers.push_back(dst.Release());
281 TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
283 dst = std::move(src);
284 TEST_EQ_FUNC(src.GetSize(), 0);
288 static void builder_reusable_after_releaseraw_and_move_assign_test(
289 TestSelector selector) {
290 if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
293 for (int i = 0; i < 5; ++i) {
294 auto root_offset1 = populate1(dst);
295 dst.Finish(root_offset1);
297 uint8_t *buf = release_raw_base(dst, size, offset);
298 TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
301 dst = std::move(src);
302 TEST_EQ_FUNC(src.GetSize(), 0);
306 #endif // !defined(FLATBUFFERS_CPP98_STL)
309 static void run_tests(TestSelector selector) {
310 builder_reusable_after_release_test(selector);
311 builder_reusable_after_releaseraw_test(selector);
313 #if !defined(FLATBUFFERS_CPP98_STL)
315 builder_reusable_after_release_and_move_assign_test(selector);
316 builder_reusable_after_releaseraw_and_move_assign_test(selector);
318 #endif // !defined(FLATBUFFERS_CPP98_STL)
323 #endif // TEST_BUILDER_H