Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose FullNameAndVersion() from a DSDL type. #352

Merged
merged 9 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/nunavut/lang/cpp/support/serialization.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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)" (<assert.h> is always included by Nunavut).
// Most platforms can simply define "NUNAVUT_ASSERT(x)=assert(x)" (<cassert> 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 <cassert> // for assert
#include <cstring> // for std::size_t
{% if not options.omit_float_serialization_support -%}
#include <cmath> // For isfinite().
Expand Down
7 changes: 4 additions & 3 deletions src/nunavut/lang/cpp/templates/_composite_type.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"; }
Copy link
Author

@serges147 serges147 Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I can't make it as simple as it could be in c++17:
static constexpr char FullNameAndVersion[] = "{{ composite_type }}"; - linker error @ c++14

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can by adding constexpr char {{composite_type|short_reference_name}}::FullNameAndVersion[]; after the class.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sonar will catch ODR issue with such approach.

{% 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.
Expand Down
2 changes: 1 addition & 1 deletion submodules/CETL
Submodule CETL updated 70 files
+1 −1 .devcontainer/devcontainer.json
+35 −15 .github/workflows/cetlvast.yml
+4 −0 .gitignore
+42 −31 .vscode/settings.json
+40 −7 CONTRIBUTING.md
+20 −14 build-tools/bin/verify.py
+6 −14 cetlvast/CMakeLists.txt
+2 −1 cetlvast/cmake/compiler_flag_sets/default.cmake
+12 −8 cetlvast/cmake/modules/Findgcovr.cmake
+6 −0 cetlvast/include/cetlvast/helpers.hpp
+100 −0 cetlvast/include/cetlvast/helpers_rtti.hpp
+66 −0 cetlvast/include/cetlvast/memory_resource_mock.hpp
+313 −0 cetlvast/include/cetlvast/smf_policies.hpp
+100 −0 cetlvast/include/cetlvast/tracking_memory_resource.hpp
+169 −0 cetlvast/include/cetlvast/typelist.hpp
+1 −1 cetlvast/suites/compile/CMakeLists.txt
+35 −0 cetlvast/suites/compile/test_unbounded_variant_footprint_get_const.cpp
+35 −0 cetlvast/suites/compile/test_unbounded_variant_footprint_get_non_const.cpp
+36 −0 cetlvast/suites/compile/test_unbounded_variant_footprint_set.cpp
+27 −0 cetlvast/suites/compile/test_unbounded_variant_zero_footprint_non_pmr.cpp
+7 −1 cetlvast/suites/docs/CMakeLists.txt
+5 −4 cetlvast/suites/docs/doxygen.ini
+151 −32 cetlvast/suites/docs/examples/example_07_polymorphic_alloc_deleter.cpp
+46 −0 cetlvast/suites/docs/examples/example_09_variant.cpp
+83 −0 cetlvast/suites/docs/examples/example_10_unbounded_variant.cpp
+3 −3 cetlvast/suites/unittest/CMakeLists.txt
+460 −0 cetlvast/suites/unittest/pmr/test_pmr_function.cpp
+251 −0 cetlvast/suites/unittest/pmr/test_pmr_interface_ptr.cpp
+1,273 −0 cetlvast/suites/unittest/test_pf17_optional.cpp
+507 −0 cetlvast/suites/unittest/test_pf17_string_view.cpp
+79 −0 cetlvast/suites/unittest/test_pf17_type_traits.cpp
+70 −0 cetlvast/suites/unittest/test_pf17_variant.hpp
+409 −0 cetlvast/suites/unittest/test_pf17_variant_assignment_1.cpp
+371 −0 cetlvast/suites/unittest/test_pf17_variant_assignment_2.cpp
+146 −0 cetlvast/suites/unittest/test_pf17_variant_assignment_3.cpp
+54 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_1.cpp
+138 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_2.cpp
+158 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_3.cpp
+63 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_4.cpp
+54 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_5.cpp
+52 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_6.cpp
+54 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_7.cpp
+52 −0 cetlvast/suites/unittest/test_pf17_variant_ctor_8.cpp
+1,011 −0 cetlvast/suites/unittest/test_pf17_variant_other.cpp
+13 −0 cetlvast/suites/unittest/test_pf20_span.cpp
+296 −0 cetlvast/suites/unittest/test_rtti.cpp
+125 −0 cetlvast/suites/unittest/test_type_traits_ext.cpp
+150 −0 cetlvast/suites/unittest/test_typelist.cpp
+1,767 −0 cetlvast/suites/unittest/test_unbounded_variant.cpp
+66 −2 cetlvast/suites/unittest/test_variable_length_array_bool.cpp
+225 −73 cetlvast/suites/unittest/test_variable_length_array_compat.cpp
+4 −4 cetlvast/suites/unittest/test_variable_length_array_debug_asserts.cpp
+48 −0 cetlvast/suites/unittest/test_variable_length_array_general_allocation.cpp
+94 −0 include/cetl/_helper_enable_copy_move.hpp
+25 −0 include/cetl/cetl.hpp
+123 −10 include/cetl/pf17/cetlpf.hpp
+888 −0 include/cetl/pf17/optional.hpp
+404 −0 include/cetl/pf17/string_view.hpp
+2 −2 include/cetl/pf17/sys/memory_resource.hpp
+118 −0 include/cetl/pf17/type_traits.hpp
+94 −0 include/cetl/pf17/utility.hpp
+1,250 −0 include/cetl/pf17/variant.hpp
+2 −5 include/cetl/pf20/span.hpp
+359 −0 include/cetl/pmr/function.hpp
+217 −0 include/cetl/pmr/interface_ptr.hpp
+369 −0 include/cetl/rtti.hpp
+235 −0 include/cetl/type_traits_ext.hpp
+1,736 −0 include/cetl/unbounded_variant.hpp
+170 −131 include/cetl/variable_length_array.hpp
+64 −0 include/cetl/visit_helpers.hpp
2 changes: 1 addition & 1 deletion submodules/googletest
Submodule googletest updated 158 files
2 changes: 1 addition & 1 deletion submodules/public_regulated_data_types
3 changes: 3 additions & 0 deletions verification/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand All @@ -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)
Expand Down
117 changes: 117 additions & 0 deletions verification/cpp/suite/test_constant.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright (c) 2024 OpenCyphal Development Team.
* Authors: Sergei Shirokov <sergei.shirokov@zubax.com>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inspired by corresponding "C" test, namely verification/c/suite/test_constant.c

* 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.
Copy link
Author

@serges147 serges147 Nov 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate issue and PR but probably I will add generation of a new <DSDL Type>::_traits_::ArrayCapacity struct (similar to existing struct TypeOf), where there will be listed static constexpr std::size_t constants for each field which has variable array type. Static array fields don't require such information (b/c std::array<> already has .size() method), but maybe just for consistency I will list them as well.

And I'm not planning to expose analog of ARRAY_IS_VARIABLE_LENGTH_ boolean.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thirtytwobits Do you agree with my future plan about above "ARRAY_CAPACITY" topic?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CETL's variable_length_array already provides max_size for this?

Copy link
Author

@serges147 serges147 Nov 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does, but under c++17 and above we use std::vector (with PMR allocator of course)

/*
// 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));
}
Loading