6 #include "monster_test_generated.h"
7 #include "flatbuffers/flatbuffers.h"
8 #include "test_assert.h"
10 using MyGame::Example::Color;
11 using MyGame::Example::Monster;
13 namespace flatbuffers {
19 template <class T, class U>
21 static const bool value = false;
25 struct is_same<T, T> {
26 static const bool value = true;
29 extern const std::string m1_name;
30 extern const Color m1_color;
31 extern const std::string m2_name;
32 extern const Color m2_color;
34 flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder);
35 flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder);
37 uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset);
39 void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf);
40 void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf);
42 bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color);
43 bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color);
45 bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color);
46 bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, 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(b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
59 flatbuffers::DefaultAllocator::dealloc(ptr, size);
62 auto root_offset2 = populate2(src);
63 src.Finish(root_offset2);
64 auto src_size = src.GetSize();
65 // Move into a released builder.
67 TEST_EQ_FUNC(b1.GetSize(), src_size);
68 TEST_ASSERT_FUNC(release_n_verify(b1, m2_name, m2_color));
69 TEST_EQ_FUNC(src.GetSize(), 0);
72 #endif // !defined(FLATBUFFERS_CPP98_STL)
75 void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder b1);
77 template <class DestBuilder, class SrcBuilder = DestBuilder>
80 #if !defined(FLATBUFFERS_CPP98_STL)
82 static void empty_builder_movector_test() {
84 size_t src_size = src.GetSize();
85 DestBuilder dst(std::move(src));
86 size_t dst_size = dst.GetSize();
87 TEST_EQ_FUNC(src_size, 0);
88 TEST_EQ_FUNC(src_size, dst_size);
91 static void nonempty_builder_movector_test() {
94 size_t src_size = src.GetSize();
95 DestBuilder dst(std::move(src));
96 TEST_EQ_FUNC(src_size, dst.GetSize());
97 TEST_EQ_FUNC(src.GetSize(), 0);
100 static void builder_movector_before_finish_test() {
102 auto root_offset1 = populate1(src);
103 DestBuilder dst(std::move(src));
104 dst.Finish(root_offset1);
105 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
106 TEST_EQ_FUNC(src.GetSize(), 0);
109 static void builder_movector_after_finish_test() {
111 auto root_offset1 = populate1(src);
112 src.Finish(root_offset1);
113 auto src_size = src.GetSize();
114 DestBuilder dst(std::move(src));
115 TEST_EQ_FUNC(dst.GetSize(), src_size);
116 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
117 TEST_EQ_FUNC(src.GetSize(), 0);
120 static void builder_move_assign_before_finish_test() {
122 auto root_offset1 = populate1(src);
125 dst = std::move(src);
126 dst.Finish(root_offset1);
127 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
128 TEST_EQ_FUNC(src.GetSize(), 0);
131 static void builder_move_assign_after_finish_test() {
133 auto root_offset1 = populate1(src);
134 src.Finish(root_offset1);
135 auto src_size = src.GetSize();
137 auto root_offset2 = populate2(dst);
138 dst.Finish(root_offset2);
139 dst = std::move(src);
140 TEST_EQ_FUNC(dst.GetSize(), src_size);
141 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
142 TEST_EQ_FUNC(src.GetSize(), 0);
145 static void builder_move_assign_after_release_test() {
147 auto root_offset1 = populate1(dst);
148 dst.Finish(root_offset1);
150 flatbuffers::DetachedBuffer dst_detached = dst.Release();
151 // detached buffer is deleted
154 auto root_offset2 = populate2(src);
155 src.Finish(root_offset2);
156 auto src_size = src.GetSize();
157 // Move into a released builder.
158 dst = std::move(src);
159 TEST_EQ_FUNC(dst.GetSize(), src_size);
160 TEST_ASSERT_FUNC(release_n_verify(dst, m2_name, m2_color));
161 TEST_EQ_FUNC(src.GetSize(), 0);
164 #endif // !defined(FLATBUFFERS_CPP98_STL)
167 static void builder_swap_before_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
168 /// Swap is allowed only when lhs and rhs are the same concrete type.
171 auto root_offset1 = populate1(src);
172 auto size1 = src.GetSize();
174 auto root_offset2 = populate2(dst);
175 auto size2 = dst.GetSize();
177 src.Finish(root_offset2);
178 dst.Finish(root_offset1);
179 TEST_EQ_FUNC(src.GetSize() > size2, true);
180 TEST_EQ_FUNC(dst.GetSize() > size1, true);
181 TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
182 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
186 static void builder_swap_after_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
187 /// Swap is allowed only when lhs and rhs are the same concrete type.
190 auto root_offset1 = populate1(src);
191 src.Finish(root_offset1);
192 auto size1 = src.GetSize();
194 auto root_offset2 = populate2(dst);
195 dst.Finish(root_offset2);
196 auto size2 = dst.GetSize();
198 TEST_EQ_FUNC(src.GetSize(), size2);
199 TEST_EQ_FUNC(dst.GetSize(), size1);
200 TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
201 TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
205 static void all_tests() {
207 #if !defined(FLATBUFFERS_CPP98_STL)
209 empty_builder_movector_test();
210 nonempty_builder_movector_test();
211 builder_movector_before_finish_test();
212 builder_movector_after_finish_test();
213 builder_move_assign_before_finish_test();
214 builder_move_assign_after_finish_test();
215 builder_move_assign_after_release_test();
216 builder_move_assign_after_releaseraw_test(DestBuilder());
218 #endif // !defined(FLATBUFFERS_CPP98_STL)
220 builder_swap_before_finish_test();
221 builder_swap_after_finish_test();
225 enum BuilderReuseTestSelector {
226 REUSABLE_AFTER_RELEASE = 1,
227 REUSABLE_AFTER_RELEASE_RAW = 2,
228 REUSABLE_AFTER_RELEASE_MESSAGE = 3,
229 REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN = 4,
230 REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN = 5,
231 REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN = 6
234 typedef std::set<BuilderReuseTestSelector> TestSelector;
236 template <class DestBuilder, class SrcBuilder>
237 struct BuilderReuseTests {
238 static void builder_reusable_after_release_test(TestSelector selector) {
239 if (!selector.count(REUSABLE_AFTER_RELEASE)) {
244 std::vector<flatbuffers::DetachedBuffer> buffers;
245 for (int i = 0; i < 5; ++i) {
246 auto root_offset1 = populate1(fbb);
247 fbb.Finish(root_offset1);
248 buffers.push_back(fbb.Release());
249 TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
253 static void builder_reusable_after_releaseraw_test(TestSelector selector) {
254 if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
259 for (int i = 0; i < 5; ++i) {
260 auto root_offset1 = populate1(fbb);
261 fbb.Finish(root_offset1);
263 uint8_t *buf = release_raw_base(fbb, size, offset);
264 TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
270 #if !defined(FLATBUFFERS_CPP98_STL)
272 static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
273 if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
278 std::vector<flatbuffers::DetachedBuffer> buffers;
279 for (int i = 0; i < 5; ++i) {
280 auto root_offset1 = populate1(dst);
281 dst.Finish(root_offset1);
282 buffers.push_back(dst.Release());
283 TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
285 dst = std::move(src);
286 TEST_EQ_FUNC(src.GetSize(), 0);
290 static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
291 if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
296 for (int i = 0; i < 5; ++i) {
297 auto root_offset1 = populate1(dst);
298 dst.Finish(root_offset1);
300 uint8_t *buf = release_raw_base(dst, size, offset);
301 TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
304 dst = std::move(src);
305 TEST_EQ_FUNC(src.GetSize(), 0);
309 #endif // !defined(FLATBUFFERS_CPP98_STL)
312 static void run_tests(TestSelector selector) {
313 builder_reusable_after_release_test(selector);
314 builder_reusable_after_releaseraw_test(selector);
316 #if !defined(FLATBUFFERS_CPP98_STL)
318 builder_reusable_after_release_and_move_assign_test(selector);
319 builder_reusable_after_releaseraw_and_move_assign_test(selector);
321 #endif // !defined(FLATBUFFERS_CPP98_STL)
326 #endif // TEST_BUILDER_H