Austin Schuh | 272c613 | 2020-11-14 16:37:52 -0800 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2014 Google Inc. All rights reserved. |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | // This is a sandbox for modeling C++17 code generator. |
| 18 | // C++17 code generator: "flatc --cpp_std c++17". |
| 19 | // Warning: |
| 20 | // This is an experimental feature and could change at any time. |
| 21 | |
| 22 | #include "flatbuffers/flatbuffers.h" |
| 23 | #include "flatbuffers/flexbuffers.h" |
| 24 | #include "flatbuffers/idl.h" |
| 25 | #include "flatbuffers/minireflect.h" |
| 26 | #include "flatbuffers/registry.h" |
| 27 | #include "flatbuffers/util.h" |
| 28 | #include "test_assert.h" |
| 29 | |
| 30 | // Embed generated code into an isolated namespace. |
| 31 | namespace cpp17 { |
| 32 | #include "generated_cpp17/monster_test_generated.h" |
| 33 | #include "generated_cpp17/optional_scalars_generated.h" |
| 34 | } // namespace cpp17 |
| 35 | |
| 36 | namespace cpp11 { |
| 37 | #include "../monster_test_generated.h" |
| 38 | #include "../optional_scalars_generated.h" |
| 39 | } // namespace cpp11 |
| 40 | |
| 41 | void CreateTableByTypeTest() { |
| 42 | flatbuffers::FlatBufferBuilder builder; |
| 43 | |
| 44 | // We will create an object of this type using only the type. |
| 45 | using type_to_create_t = cpp17::MyGame::Example::Stat; |
| 46 | |
| 47 | [&builder] { |
| 48 | auto id_str = builder.CreateString("my_id"); |
| 49 | auto table = type_to_create_t::Traits::Create(builder, id_str, 42, 7); |
| 50 | // Be sure that the correct return type was inferred. |
| 51 | static_assert( |
| 52 | std::is_same_v<decltype(table), flatbuffers::Offset<type_to_create_t>>); |
| 53 | builder.Finish(table); |
| 54 | }(); |
| 55 | |
| 56 | // Access it. |
| 57 | auto stat = |
| 58 | flatbuffers::GetRoot<type_to_create_t>(builder.GetBufferPointer()); |
| 59 | TEST_EQ_STR(stat->id()->c_str(), "my_id"); |
| 60 | TEST_EQ(stat->val(), 42); |
| 61 | TEST_EQ(stat->count(), 7); |
| 62 | } |
| 63 | |
| 64 | void OptionalScalarsTest() { |
| 65 | static_assert(std::is_same<flatbuffers::Optional<float>, std::optional<float>>::value); |
| 66 | static_assert(std::is_same<flatbuffers::nullopt_t, std::nullopt_t>::value); |
| 67 | |
| 68 | // test C++ nullable |
| 69 | flatbuffers::FlatBufferBuilder fbb; |
| 70 | FinishScalarStuffBuffer(fbb, cpp17::optional_scalars::CreateScalarStuff( |
| 71 | fbb, 1, static_cast<int8_t>(2))); |
| 72 | auto opts = |
| 73 | cpp17::optional_scalars::GetMutableScalarStuff(fbb.GetBufferPointer()); |
| 74 | TEST_ASSERT(!opts->maybe_bool()); |
| 75 | TEST_ASSERT(!opts->maybe_f32().has_value()); |
| 76 | TEST_ASSERT(opts->maybe_i8().has_value()); |
| 77 | TEST_EQ(opts->maybe_i8().value(), 2); |
| 78 | TEST_ASSERT(opts->mutate_maybe_i8(3)); |
| 79 | TEST_ASSERT(opts->maybe_i8().has_value()); |
| 80 | TEST_EQ(opts->maybe_i8().value(), 3); |
| 81 | TEST_ASSERT(!opts->mutate_maybe_i16(-10)); |
| 82 | |
| 83 | cpp17::optional_scalars::ScalarStuffT obj; |
| 84 | opts->UnPackTo(&obj); |
| 85 | TEST_ASSERT(!obj.maybe_bool); |
| 86 | TEST_ASSERT(!obj.maybe_f32.has_value()); |
| 87 | TEST_ASSERT(obj.maybe_i8.has_value() && obj.maybe_i8.value() == 3); |
| 88 | TEST_ASSERT(obj.maybe_i8 && *obj.maybe_i8 == 3); |
| 89 | obj.maybe_i32 = -1; |
| 90 | |
| 91 | fbb.Clear(); |
| 92 | FinishScalarStuffBuffer( |
| 93 | fbb, cpp17::optional_scalars::ScalarStuff::Pack(fbb, &obj)); |
| 94 | opts = cpp17::optional_scalars::GetMutableScalarStuff(fbb.GetBufferPointer()); |
| 95 | TEST_ASSERT(opts->maybe_i8().has_value()); |
| 96 | TEST_EQ(opts->maybe_i8().value(), 3); |
| 97 | TEST_ASSERT(opts->maybe_i32().has_value()); |
| 98 | TEST_EQ(opts->maybe_i32().value(), -1); |
| 99 | |
| 100 | TEST_EQ(std::optional<int32_t>(opts->maybe_i32()).value(), -1); |
| 101 | TEST_EQ(std::optional<int64_t>(opts->maybe_i32()).value(), -1); |
| 102 | TEST_ASSERT(opts->maybe_i32() == std::optional<int64_t>(-1)); |
| 103 | } |
| 104 | |
| 105 | int FlatBufferCpp17Tests() { |
| 106 | CreateTableByTypeTest(); |
| 107 | OptionalScalarsTest(); |
| 108 | return 0; |
| 109 | } |
| 110 | |
| 111 | int main(int /*argc*/, const char * /*argv*/[]) { |
| 112 | InitTestEngine(); |
| 113 | |
| 114 | FlatBufferCpp17Tests(); |
| 115 | |
| 116 | if (!testing_fails) { |
| 117 | TEST_OUTPUT_LINE("C++17: ALL TESTS PASSED"); |
| 118 | } else { |
| 119 | TEST_OUTPUT_LINE("C++17: %d FAILED TESTS", testing_fails); |
| 120 | } |
| 121 | return CloseTestEngine(); |
| 122 | } |