diff --git a/src/nunavut/lang/cpp/support/serialization.j2 b/src/nunavut/lang/cpp/support/serialization.j2 index c8c00302..41e428ff 100644 --- a/src/nunavut/lang/cpp/support/serialization.j2 +++ b/src/nunavut/lang/cpp/support/serialization.j2 @@ -41,12 +41,13 @@ static_assert(__cplusplus >= 201402L, #ifndef NUNAVUT_ASSERT // By default Nunavut does not generate assert statements since the logic to halt a program is platform // dependent and because this header requires an absolute minimum from a platform and from the C standard library. -// Most platforms can simply define "NUNAVUT_ASSERT(x)=assert(x)" ( is always included by Nunavut). +// Most platforms can simply define "NUNAVUT_ASSERT(x)=assert(x)" ( is always included by Nunavut). # error "You must either define NUNAVUT_ASSERT or you need to disable assertions" \ " when generating serialization support code using Nunavut language options" #endif {% endif -%} +#include // for assert #include // for std::size_t {% if not options.omit_float_serialization_support -%} #include // For isfinite(). diff --git a/src/nunavut/lang/cpp/templates/_composite_type.j2 b/src/nunavut/lang/cpp/templates/_composite_type.j2 index c7ef3f59..ef35856e 100644 --- a/src/nunavut/lang/cpp/templates/_composite_type.j2 +++ b/src/nunavut/lang/cpp/templates/_composite_type.j2 @@ -61,10 +61,11 @@ struct {% if composite_type.deprecated -%} static constexpr bool IsService = false; static constexpr bool IsRequest = {{ (composite_type == T.request_type) | string | lower }}; static constexpr bool IsResponse = {{ (composite_type == T.response_type) | string | lower }}; -{%- else %} +{% else %} static constexpr bool IsServiceType = false; -{% endif -%} - {%- assert composite_type.extent % 8 == 0 %} +{% endif %} + static constexpr const char* FullNameAndVersion() { return "{{ composite_type }}"; } + {% assert composite_type.extent % 8 == 0 %} {%- assert composite_type.inner_type.extent % 8 == 0 %} /// Extent is the minimum amount of memory required to hold any serialized representation of any compatible /// version of the data type; or, on other words, it is the the maximum possible size of received objects of this type. diff --git a/submodules/CETL b/submodules/CETL index d2f0af34..ccd53164 160000 --- a/submodules/CETL +++ b/submodules/CETL @@ -1 +1 @@ -Subproject commit d2f0af34f7d5487b3004ba9b95fb9d8cd42f0174 +Subproject commit ccd5316400ace5475ce3f9b5c223f17d38f246e0 diff --git a/submodules/googletest b/submodules/googletest index b796f7d4..d1440319 160000 --- a/submodules/googletest +++ b/submodules/googletest @@ -1 +1 @@ -Subproject commit b796f7d44681514f58a683a3a71ff17c94edb0c1 +Subproject commit d144031940543e15423a25ae5a8a74141044862f diff --git a/submodules/o1heap b/submodules/o1heap index bd932773..10e2754a 160000 --- a/submodules/o1heap +++ b/submodules/o1heap @@ -1 +1 @@ -Subproject commit bd9327732b43ec84d5e44b90f343157ae3240d75 +Subproject commit 10e2754a3b721b77d1f3f92227f3a64ad546f956 diff --git a/submodules/public_regulated_data_types b/submodules/public_regulated_data_types index 70573cb9..f9f67906 160000 --- a/submodules/public_regulated_data_types +++ b/submodules/public_regulated_data_types @@ -1 +1 @@ -Subproject commit 70573cb98a346f5a9aee54ce421a8a79700df2b4 +Subproject commit f9f67906cc0ca5d7c1b429924852f6b28f313cbf diff --git a/submodules/unity b/submodules/unity index 1d28a998..73237c5d 160000 --- a/submodules/unity +++ b/submodules/unity @@ -1 +1 @@ -Subproject commit 1d28a9981207fa03be19018f60b23d5dca53cabc +Subproject commit 73237c5d224169c7b4d2ec8321f9ac92e8071708 diff --git a/verification/CMakeLists.txt b/verification/CMakeLists.txt index 992b8b8d..863cdebe 100644 --- a/verification/CMakeLists.txt +++ b/verification/CMakeLists.txt @@ -390,6 +390,8 @@ function(runTestCpp) # target_compile_options(${NATIVE_TEST_NAME} PRIVATE "-Wno-old-style-cast") endif() + # Some tests use deprecated DSDLs + target_compile_options(${NATIVE_TEST_NAME} PRIVATE "-Wno-deprecated-declarations") target_link_libraries(${NATIVE_TEST_NAME} PUBLIC o1heap) target_include_directories(${NATIVE_TEST_NAME} PUBLIC "${NUNAVUT_PROJECT_ROOT}/submodules/CETL/include") define_native_test_run(TEST_NAME ${NATIVE_TEST_NAME} OUTDIR ${NUNAVUT_VERIFICATIONS_BINARY_DIR}) @@ -412,6 +414,7 @@ if (NUNAVUT_VERIFICATION_LANG STREQUAL "cpp") runTestCpp(TEST_FILE test_large_bitset.cpp LINK dsdl-regulated dsdl-test LANGUAGE_FLAVORS c++14 c++17 c++17-pmr c++20 c++20-pmr) runTestCpp(TEST_FILE test_serialization.cpp LINK dsdl-regulated dsdl-test LANGUAGE_FLAVORS c++14 c++17 c++17-pmr c++20 c++20-pmr) runTestCpp(TEST_FILE test_unionant.cpp LINK dsdl-regulated dsdl-test LANGUAGE_FLAVORS c++14 cetl++14-17 c++17 c++17-pmr c++20 c++20-pmr) + runTestCpp(TEST_FILE test_constant.cpp LINK dsdl-regulated dsdl-test LANGUAGE_FLAVORS c++14 c++17 c++17-pmr c++20 c++20-pmr) endif() function(runTestC) diff --git a/verification/cpp/suite/test_constant.cpp b/verification/cpp/suite/test_constant.cpp new file mode 100644 index 00000000..3a0d39d0 --- /dev/null +++ b/verification/cpp/suite/test_constant.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2024 OpenCyphal Development Team. + * Authors: Sergei Shirokov + * This software is distributed under the terms of the MIT License. + * + * Tests of constant + */ + +#include "gmock/gmock.h" +#include "regulated/basics/Struct__0_1.hpp" +#include "regulated/basics/Union_0_1.hpp" +#include "regulated/basics/Service_0_1.hpp" + +using testing::Le; +using testing::StrEq; +using testing::FloatNear; +using testing::DoubleNear; + +TEST(ConstantTests, Struct) +{ + // Type parameters. + EXPECT_TRUE(regulated::basics::Struct__0_1::_traits_::HasFixedPortID); + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::FixedPortId, 7000); + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::FullNameAndVersion(), StrEq("regulated.basics.Struct_.0.1")); + + // Application constants. + EXPECT_THAT(regulated::basics::Struct__0_1::CONSTANT_MINUS_THREE, DoubleNear(-3.0, 1e-9)); + EXPECT_THAT(regulated::basics::Struct__0_1::CONSTANT_ZEE, 'Z'); + EXPECT_THAT(-regulated::basics::Struct__0_1::CONSTANT_MINUS_MAX_OFFSET, + Le(regulated::basics::Struct__0_1::_traits_::SerializationBufferSizeBytes * 8U)); + EXPECT_TRUE(regulated::basics::Struct__0_1::CONSTANT_TRUTH); + +// TODO: Uncomment when some form of "ARRAY_CAPACITY" is generated. +/* + // Field metadata. Expected values encoded in the field names. + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::i10_4_ARRAY_CAPACITY_, 4); + EXPECT_FALSE(regulated::basics::Struct__0_1::_traits_::i10_4_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::f16_le2_ARRAY_CAPACITY_, 2); + EXPECT_TRUE(regulated::basics::Struct__0_1::_traits_::f16_le2_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::unaligned_bitpacked_3_ARRAY_CAPACITY_, 3); + EXPECT_FALSE(regulated::basics::Struct__0_1::_traits_::unaligned_bitpacked_3_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::bytes_lt3_ARRAY_CAPACITY_, 2); + EXPECT_TRUE(regulated::basics::Struct__0_1::_traits_::bytes_lt3_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::bytes_3_ARRAY_CAPACITY_, 3); + EXPECT_FALSE(regulated::basics::Struct__0_1::_traits_::bytes_3_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::u2_le4_ARRAY_CAPACITY_, 4); + EXPECT_TRUE(regulated::basics::Struct__0_1::_traits_::u2_le4_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::delimited_fix_le2_ARRAY_CAPACITY_, 2); + EXPECT_TRUE(regulated::basics::Struct__0_1::_traits_::delimited_fix_le2_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::u16_2_ARRAY_CAPACITY_, 2); + EXPECT_FALSE(regulated::basics::Struct__0_1::_traits_::u16_2_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::aligned_bitpacked_3_ARRAY_CAPACITY_, 3); + EXPECT_FALSE(regulated::basics::Struct__0_1::_traits_::aligned_bitpacked_3_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::unaligned_bitpacked_lt3_ARRAY_CAPACITY_, 2); + EXPECT_TRUE(regulated::basics::Struct__0_1::_traits_::unaligned_bitpacked_lt3_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::delimited_var_2_ARRAY_CAPACITY_, 2); + EXPECT_FALSE(regulated::basics::Struct__0_1::_traits_::delimited_var_2_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Struct__0_1::_traits_::aligned_bitpacked_le3_ARRAY_CAPACITY_, 3); + EXPECT_TRUE(regulated::basics::Struct__0_1::_traits_::aligned_bitpacked_le3_ARRAY_IS_VARIABLE_LENGTH_); +*/ +} + +TEST(ConstantTests, Union) +{ + // Type parameters. + EXPECT_FALSE(regulated::basics::Union_0_1::_traits_::HasFixedPortID); + EXPECT_THAT(regulated::basics::Union_0_1::_traits_::FullNameAndVersion(), StrEq("regulated.basics.Union.0.1")); + EXPECT_THAT(regulated::basics::Union_0_1::_traits_::ExtentBytes, + 1U + regulated::basics::Struct__0_1::_traits_::ExtentBytes); // Largest option + union tag field + EXPECT_THAT(regulated::basics::Union_0_1::VariantType::MAX_INDEX, 3); + +// TODO: Uncomment when some form of "ARRAY_CAPACITY" is generated. +/* + // Field metadata. Expected values encoded in the field names. + EXPECT_THAT(regulated::basics::Union_0_1::_traits__delimited_fix_le2_ARRAY_CAPACITY_, 2); + EXPECT_FALSE(regulated::basics::Union_0_1::_traits__delimited_fix_le2_ARRAY_IS_VARIABLE_LENGTH_); + + EXPECT_THAT(regulated::basics::Union_0_1::_traits__delimited_var_le2_ARRAY_CAPACITY_, 2); + EXPECT_TRUE(regulated::basics::Union_0_1::_traits__delimited_var_le2_ARRAY_IS_VARIABLE_LENGTH_); +*/ +} + +TEST(ConstantTests, Service) +{ + // Type parameters. + EXPECT_TRUE(regulated::basics::Service_0_1::_traits_::IsService); + EXPECT_TRUE(regulated::basics::Service_0_1::_traits_::IsServiceType); + + EXPECT_FALSE(regulated::basics::Service::Request_0_1::_traits_::IsService); + EXPECT_TRUE(regulated::basics::Service::Request_0_1::_traits_::IsServiceType); + EXPECT_TRUE(regulated::basics::Service::Request_0_1::_traits_::IsRequest); + EXPECT_FALSE(regulated::basics::Service::Request_0_1::_traits_::IsResponse); + EXPECT_THAT(regulated::basics::Service::Request_0_1::_traits_::FullNameAndVersion(), + StrEq("regulated.basics.Service.Request.0.1")); + + EXPECT_FALSE(regulated::basics::Service::Response_0_1::_traits_::IsService); + EXPECT_TRUE(regulated::basics::Service::Response_0_1::_traits_::IsServiceType); + EXPECT_TRUE(regulated::basics::Service::Response_0_1::_traits_::IsResponse); + EXPECT_FALSE(regulated::basics::Service::Response_0_1::_traits_::IsRequest); + EXPECT_THAT(regulated::basics::Service::Response_0_1::_traits_::FullNameAndVersion(), + StrEq("regulated.basics.Service.Response.0.1")); + + // Application constants. + EXPECT_THAT(regulated::basics::Service::Request_0_1::HALF, DoubleNear(0.5, 1e-9)); + EXPECT_THAT(regulated::basics::Service::Response_0_1::ONE_TENTH, FloatNear(0.1f, 1e-9f)); +}