diff --git a/.github/actions/install-router-subpackage-windows/action.yml b/.github/actions/install-router-subpackage-windows/action.yml index a560f7f11..1cf514487 100644 --- a/.github/actions/install-router-subpackage-windows/action.yml +++ b/.github/actions/install-router-subpackage-windows/action.yml @@ -1,6 +1,10 @@ name: Install DDS Router subpackages description: Install and setup DDS Router subpackages for linking and building application in Windows inputs: + cmake_extra_args: + description: 'Specifies cmake arguments different from default' + required: false + default: ' ' cmake_build_type: description: 'Specifies the build type on single-configuration generators' required: true @@ -17,6 +21,7 @@ runs: - run: > cmake -DCMAKE_PREFIX_PATH='C:\Program Files\gtest;C:\Program Files\yamlcpp;C:\Program Files;${{ github.workspace }}\..\fastdds\install' ` -DCMAKE_CXX_FLAGS="/WX /EHsc" -DBUILD_TOOL_TESTS=ON -DBUILD_LIBRARY_TESTS=ON ` + ${{ inputs.cmake_extra_args }} ` -B build\${{ inputs.subpackage }} -A x64 -T host=x64 DDS-Router/${{ inputs.subpackage_dir }}; cmake --build build\${{ inputs.subpackage }} --config ${{ inputs.cmake_build_type }} --target install; diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3a7a0a890..9ee5c5a30 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -102,9 +102,17 @@ jobs: subpackage: ddsrouter_cmake subpackage_dir: ddsrouter_cmake + # This is needed for windows 2019 to use /Zc:preprocessor to use c++ std preprocessor for ENUMERATION_BUILDER + # due to a windows 2019 SDK non bug + - name: Set environment variables for Windows 2019 build + run: | + echo ("W2019_CMAKE_EXTRA_ARGS=-DCMAKE_SYSTEM_VERSION=10.0.19041.0") >> $env:GITHUB_ENV + if: contains( matrix.windows-version , '2019') + - name: Install ddsrouter_utils uses: ./DDS-Router/.github/actions/install-router-subpackage-windows with: + cmake_extra_args: ${{ env.W2019_CMAKE_EXTRA_ARGS }} cmake_build_type: ${{ matrix.cmake-config }} subpackage: ddsrouter_utils subpackage_dir: ddsrouter_utils diff --git a/ddsrouter_cmake/cmake/cpp_common/configure_project_cpp.cmake b/ddsrouter_cmake/cmake/cpp_common/configure_project_cpp.cmake index 9e1b2e742..0113cc73b 100644 --- a/ddsrouter_cmake/cmake/cpp_common/configure_project_cpp.cmake +++ b/ddsrouter_cmake/cmake/cpp_common/configure_project_cpp.cmake @@ -57,6 +57,9 @@ macro(configure_project_cpp) activate_code_coverage() endif() + # Set custom C++ Flags + custom_cpp_flags() + # Finish macro message(STATUS "C++ Project ${MODULE_NAME_LARGE} configured.") diff --git a/ddsrouter_cmake/cmake/cpp_common/cpp_flags.cmake b/ddsrouter_cmake/cmake/cpp_common/cpp_flags.cmake new file mode 100644 index 000000000..073ce08c9 --- /dev/null +++ b/ddsrouter_cmake/cmake/cpp_common/cpp_flags.cmake @@ -0,0 +1,28 @@ +# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +############################################################################### +# CMake Build Type +############################################################################### + +# Set custom CMAKE_CXX_FLAGS +macro(custom_cpp_flags) + + # Only for windows + if(MSVC OR MSVC_IDE) + # Set standard preprocessor + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:preprocessor") + endif() + +endmacro() diff --git a/ddsrouter_core/src/cpp/participant/implementations/auxiliar/BaseParticipant.hpp b/ddsrouter_core/src/cpp/participant/implementations/auxiliar/BaseParticipant.hpp index 2ff2df3fa..ff696b92e 100644 --- a/ddsrouter_core/src/cpp/participant/implementations/auxiliar/BaseParticipant.hpp +++ b/ddsrouter_core/src/cpp/participant/implementations/auxiliar/BaseParticipant.hpp @@ -19,7 +19,7 @@ #ifndef __SRC_DDSROUTERCORE_PARTICIPANT_IMPLEMENTATIONS_AUXILIAR_BASEPARTICIPANT_HPP_ #define __SRC_DDSROUTERCORE_PARTICIPANT_IMPLEMENTATIONS_AUXILIAR_BASEPARTICIPANT_HPP_ -#include +#include #include diff --git a/ddsrouter_utils/include/ddsrouter_utils/Log.hpp b/ddsrouter_utils/include/ddsrouter_utils/Log.hpp index b18b4cd97..f9a4a01ba 100644 --- a/ddsrouter_utils/include/ddsrouter_utils/Log.hpp +++ b/ddsrouter_utils/include/ddsrouter_utils/Log.hpp @@ -22,7 +22,7 @@ // Use FastDDS log #include -#include +#include namespace eprosima { namespace ddsrouter { diff --git a/ddsrouter_utils/include/ddsrouter_utils/macros/custom_enumeration.hpp b/ddsrouter_utils/include/ddsrouter_utils/macros/custom_enumeration.hpp new file mode 100644 index 000000000..a609a6b86 --- /dev/null +++ b/ddsrouter_utils/include/ddsrouter_utils/macros/custom_enumeration.hpp @@ -0,0 +1,95 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file macros.hpp + * + * This file contains constant values common for the whole project + */ + +#ifndef _DDSROUTERUTILS_MACROS_CUSTOMENUMERATION_HPP_ +#define _DDSROUTERUTILS_MACROS_CUSTOMENUMERATION_HPP_ + +#include +#include + +#include +#include +#include + +namespace eprosima { +namespace ddsrouter { +namespace utils { + +/** + * @brief This macro creates a Custom Enumeration with auxiliary functions and variables. + * + * An enumeration built with ENUEMERATION_BUILDER has: + * - enum class with name \c enumeration_name and N values, one for each extra argument, and with that exact name. + * - array called \c nammes_ with the names of each element of the enumeration + * as strings of the enum value. + * - \c to_string method to get the string associated with an enumeration value. + * - \c from_string_ method that gives enumeration value from string name. + * - operator << for each enumeration value using to_string . + * - \c N_VALUES_ unsigned int to get the number of elements in the enumeration. + * + * @arg enumeration_name it sets the enum class name and is used to name variables and methods. + * @arg extra_arguments each of the elements of the enum class. Their conversion to string would use this same name. + * + * @note empty custom enumerations are not allowed, even when empty enum class are. + * + * @example + * ENUMERATION_BUILDER(CustomEnum, el1, el2); + * CustomEnum my_value = CustomEnum::el1; // Set my_value as el1 = 0 + * my_value = from_string_CustomEnum("el2"); // Set my_value as el2 = 1 + * to_string(my_value); // = "el2" + */ +#define ENUMERATION_BUILDER(enumeration_name, ...) \ + \ + /* Forbid empty enumerations */ \ + static_assert( COUNT_ARGUMENTS(__VA_ARGS__), "Empty Enumerations are not allowed."); \ + \ + /* Declare enumeration */ \ + enum class enumeration_name {__VA_ARGS__ \ + }; \ + \ + /* Initialize name arrays */ \ + const std::array names_ ## enumeration_name = \ + { APPLY_MACRO_FOR_EACH(STRINGIFY_WITH_COMMA, __VA_ARGS__) }; \ + \ + /* To string method */ \ + const std::string& to_string(const enumeration_name& e) \ + { return names_ ## enumeration_name[static_cast(e)]; } \ + \ + /* From string */ \ + enumeration_name from_string_ ## enumeration_name(const std::string& s) \ + { \ + for (int i = 0; i < COUNT_ARGUMENTS(__VA_ARGS__); i++) \ + if (names_ ## enumeration_name[i] == s)return static_cast(i); \ + throw eprosima::ddsrouter::utils::InitializationException( \ + STR_ENTRY << "Not correct name " << s << " for Enum " << STRINGIFY(enumeration_name) << "."); \ + } \ + \ + /* Serialization operation */ \ + std::ostream& operator <<(std::ostream& os, const enumeration_name& e) { os << to_string(e); return os; } \ + \ + /* Number of elements in enumeration */ \ + constexpr const unsigned int N_VALUES_ ## enumeration_name = COUNT_ARGUMENTS(__VA_ARGS__); + + +} /* namespace utils */ +} /* namespace ddsrouter */ +} /* namespace eprosima */ + +#endif /* _DDSROUTERUTILS_MACROS_CUSTOMENUMERATION_HPP_ */ diff --git a/ddsrouter_utils/include/ddsrouter_utils/macros.hpp b/ddsrouter_utils/include/ddsrouter_utils/macros/macros.hpp similarity index 54% rename from ddsrouter_utils/include/ddsrouter_utils/macros.hpp rename to ddsrouter_utils/include/ddsrouter_utils/macros/macros.hpp index 3dc80494d..98ced0c49 100644 --- a/ddsrouter_utils/include/ddsrouter_utils/macros.hpp +++ b/ddsrouter_utils/include/ddsrouter_utils/macros/macros.hpp @@ -18,8 +18,8 @@ * This file contains constant values common for the whole project */ -#ifndef _DDSROUTERUTILS_MACROS_HPP_ -#define _DDSROUTERUTILS_MACROS_HPP_ +#ifndef _DDSROUTERUTILS_MACROS_MACROS_HPP_ +#define _DDSROUTERUTILS_MACROS_MACROS_HPP_ #include @@ -27,16 +27,49 @@ namespace eprosima { namespace ddsrouter { namespace utils { +///////////////////////// +// FORMAT +///////////////////////// + +/** + * @brief Get string of the argument passed to the macro + * + * @example + * STRINGIFY(value) = "value" + */ #define STRINGIFY(x) #x +//! Same as \c STRINGIFY but adding a comma "," at the end +#define STRINGIFY_WITH_COMMA(x) #x, + + +///////////////////////// +// TYPES +///////////////////////// + +/** + * @brief Force the specialization type of a template to be a subclass of a Class. + * + * @example + * FORCE_TEMPLATE_SUBCLASS(A, B) = static assert <=> B not inherit from A + * + * @param base parent class that \c derived must inherit. + * @param derived specialization class. + */ #define FORCE_TEMPLATE_SUBCLASS(base, derived) \ static_assert(std::is_base_of::value, STRINGIFY(derived) " class not derived from " STRINGIFY(base)) -// TODO: probably in the future is needed to create a utils method that transforms this name to a human reasonable name +/** + * @brief Get string of the name of the CPP Data Type of the argument + * + * @example + * STRINGIFY(int) = "j" + * STRINGIFY(string) = "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE" + */ #define TYPE_NAME(x) typeid(x).name() } /* namespace utils */ } /* namespace ddsrouter */ } /* namespace eprosima */ -#endif /* _DDSROUTERUTILS_MACROS_HPP_ */ +#endif /* _DDSROUTERUTILS_MACROS_MACROS_HPP_ */ diff --git a/ddsrouter_utils/include/ddsrouter_utils/macros/recursive_macros.hpp b/ddsrouter_utils/include/ddsrouter_utils/macros/recursive_macros.hpp new file mode 100644 index 000000000..a799ec046 --- /dev/null +++ b/ddsrouter_utils/include/ddsrouter_utils/macros/recursive_macros.hpp @@ -0,0 +1,115 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file recursive_macros.hpp + * + * This file contains constant values common for the whole project + */ + +#ifndef _DDSROUTERUTILS_MACROS_RECURSIVEMACROS_HPP_ +#define _DDSROUTERUTILS_MACROS_RECURSIVEMACROS_HPP_ + +#include + +namespace eprosima { +namespace ddsrouter { +namespace utils { + +///////////////////////// +// COUNT ARGUMENTS +///////////////////////// + +/** + * @brief Get 11th macro. + * + * @note This macro is used in \c COUNT_ARGUMENT macro. + */ +#define _ELEVENTH_ARGUMENT(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) \ + a11 + +/** + * @brief Count number of arguments in a variadic macro with maximum 9 variables + * + * @note This is an auxiliary macro that encapsulates the funtionality of \c COUNT_ARGUMENTS so that macro + * could be changed to a higher value without breaking API. + * + * @note \c dummy value is required to non argument calls. + */ +#define _COUNT_ARGUMENTS__UP_TO_NINE(...) \ + _ELEVENTH_ARGUMENT(dummy, ## __VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +/** + * @brief Count number of arguments in a variadic macro + * + * @warning This macro only allows up to 9 values. + * + * @note if more arguments required, change \c _ELEVENTH_ARGUMENT for a higher one. + * + * @example + * COUNT_ARGUMENTS(el1, el2, el3) = 3 + */ +#define COUNT_ARGUMENTS(...) \ + _COUNT_ARGUMENTS__UP_TO_NINE(__VA_ARGS__) + + +///////////////////////// +// FOR EACH +///////////////////////// + +/** + * @brief These macros allow to create an iterative APPLY_MACRO_FOR_EACH loop over every argument. + * + * Each item of form \c _FE_N allow to evaluate the function \c ACTION for the next \c N arguments. + */ +#define _FE_1(ACTION, X) ACTION(X) +#define _FE_2(ACTION, X, ...) ACTION(X) _FE_1(ACTION, __VA_ARGS__) +#define _FE_3(ACTION, X, ...) ACTION(X) _FE_2(ACTION, __VA_ARGS__) +#define _FE_4(ACTION, X, ...) ACTION(X) _FE_3(ACTION, __VA_ARGS__) +#define _FE_5(ACTION, X, ...) ACTION(X) _FE_4(ACTION, __VA_ARGS__) +#define _FE_6(ACTION, X, ...) ACTION(X) _FE_5(ACTION, __VA_ARGS__) +#define _FE_7(ACTION, X, ...) ACTION(X) _FE_6(ACTION, __VA_ARGS__) +#define _FE_8(ACTION, X, ...) ACTION(X) _FE_7(ACTION, __VA_ARGS__) +#define _FE_9(ACTION, X, ...) ACTION(X) _FE_8(ACTION, __VA_ARGS__) +//... repeat as needed + +/** + * @brief Get the 9th argument + * + * @note this is useful for \c APPLY_MACRO_FOR_EACH macro. + */ +#define _GET_NINTH_ARGUMENT(_1, _2, _3, _4, _5, _6, _7, _8, _9, NAME, ...) \ + NAME + +#define _APPLY_MACRO_FOR_EACH__UP_TO_NINE(action, ...) \ + _GET_NINTH_ARGUMENT(__VA_ARGS__, _FE_9, _FE_8, _FE_7, _FE_6, _FE_5, _FE_4, _FE_3, _FE_2, _FE_1)(action, __VA_ARGS__) + +/** + * @brief Execute \c action (must be a macro) for every argument after it. + * + * @warning This macro only allows up to 9 values. + * + * @note if more arguments required, change \c _APPLY_MACRO_FOR_EACH__UP_TO_NINE for a higher one. + * + * @example + * APPLY_MACRO_FOR_EACH(print, el1, el2, el3) => print(el1); print(el2); print(el3); + */ +#define APPLY_MACRO_FOR_EACH(action, ...) \ + _APPLY_MACRO_FOR_EACH__UP_TO_NINE(action, __VA_ARGS__) + +} /* namespace utils */ +} /* namespace ddsrouter */ +} /* namespace eprosima */ + +#endif /* _DDSROUTERUTILS_MACROS_RECURSIVEMACROS_HPP_ */ diff --git a/ddsrouter_utils/include/ddsrouter_utils/utils.hpp b/ddsrouter_utils/include/ddsrouter_utils/utils.hpp index 83924ee86..d20b513f9 100644 --- a/ddsrouter_utils/include/ddsrouter_utils/utils.hpp +++ b/ddsrouter_utils/include/ddsrouter_utils/utils.hpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include diff --git a/ddsrouter_utils/test/unittest/CMakeLists.txt b/ddsrouter_utils/test/unittest/CMakeLists.txt index abf50752f..b9920d846 100644 --- a/ddsrouter_utils/test/unittest/CMakeLists.txt +++ b/ddsrouter_utils/test/unittest/CMakeLists.txt @@ -15,6 +15,7 @@ # Add test subdirectories add_subdirectory(event) add_subdirectory(exception) +add_subdirectory(macros) add_subdirectory(math) add_subdirectory(memory) add_subdirectory(return_code) diff --git a/ddsrouter_utils/test/unittest/macros/CMakeLists.txt b/ddsrouter_utils/test/unittest/macros/CMakeLists.txt new file mode 100644 index 000000000..cce5896c3 --- /dev/null +++ b/ddsrouter_utils/test/unittest/macros/CMakeLists.txt @@ -0,0 +1,110 @@ +# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +##################################### +# STD MACROS TEST +##################################### + +set(TEST_NAME macrosTest) + +set(TEST_SOURCES + macrosTest.cpp + ) + +set(TEST_LIST + stringify + ) + +set(TEST_EXTRA_LIBRARIES + ) + +set(TEST_NEEDED_SOURCES + ) + +add_unittest_executable( + "${TEST_NAME}" + "${TEST_SOURCES}" + "${TEST_LIST}" + "${TEST_EXTRA_LIBRARIES}" + "${TEST_NEEDED_SOURCES}" + ) + +##################################### +# RECURSIVE MACROS TEST +##################################### + +set(TEST_NAME recursiveMacrosTest) + +set(TEST_SOURCES + recursiveMacrosTest.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/Formatter.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/exception/Exception.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/utils.cpp + ) + +set(TEST_LIST + count_arguments + apply_macro_for_each + ) + +set(TEST_EXTRA_LIBRARIES + fastcdr + fastrtps + $<$:iphlpapi$Shlwapi> + ) + +set(TEST_NEEDED_SOURCES + ) + +add_unittest_executable( + "${TEST_NAME}" + "${TEST_SOURCES}" + "${TEST_LIST}" + "${TEST_EXTRA_LIBRARIES}" + "${TEST_NEEDED_SOURCES}" + ) + +##################################### +# ENUMERATION BUILDER TEST +##################################### + +set(TEST_NAME enumerationBuilderMacrosTest) + +set(TEST_SOURCES + enumerationBuilderMacrosTest.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/Formatter.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/exception/Exception.cpp + ) + +set(TEST_LIST + show_how + from_string + to_string + serializator + n_values + ) + +set(TEST_EXTRA_LIBRARIES + ) + +set(TEST_NEEDED_SOURCES + ) + +add_unittest_executable( + "${TEST_NAME}" + "${TEST_SOURCES}" + "${TEST_LIST}" + "${TEST_EXTRA_LIBRARIES}" + "${TEST_NEEDED_SOURCES}" + ) diff --git a/ddsrouter_utils/test/unittest/macros/enumerationBuilderMacrosTest.cpp b/ddsrouter_utils/test/unittest/macros/enumerationBuilderMacrosTest.cpp new file mode 100644 index 000000000..5aa1fab8a --- /dev/null +++ b/ddsrouter_utils/test/unittest/macros/enumerationBuilderMacrosTest.cpp @@ -0,0 +1,153 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include + +#include + +namespace test { + +// This will create a TestCustomEnum enum class with these values. +ENUMERATION_BUILDER( + TestCustomEnum, + el0, + el1, + other_element, + noElement_atAll_00 + ); + +// Number of elements in TestCustomEnum +constexpr unsigned int NUMBER_OF_ELEMENTS = 4; + +// Each of the elements of TestCustomEnum +const std::array enum_values = +{ + TestCustomEnum::el0, + TestCustomEnum::el1, + TestCustomEnum::other_element, + TestCustomEnum::noElement_atAll_00, +}; + +// Each of the names of TestCustomEnum +const std::array string_values = +{ + "el0", + "el1", + "other_element", + "noElement_atAll_00", +}; + +// This tests that two calls to ENUMERATION_BUILDER are possible. +ENUMERATION_BUILDER( + TestCustomOtherEnum, + el0 + ); + +// This should be forbidden and would not compile +/* + ENUMERATION_BUILDER( + TestEmptyEnum + ); + */ + +} /* namespace test */ + +/** + * This test only shows how to use the ENUMERATION_BUILDER macro. + */ +TEST(enumerationBuilderMacrosTest, show_how) +{ + // Get a new element of value el0 + test::TestCustomEnum value = test::TestCustomEnum::el0; + + // Compare string of value + ASSERT_EQ("el0", test::to_string(value)); + + // Get it from a string + value = test::from_string_TestCustomEnum("el1"); + + // Compare string of value + ASSERT_EQ("el1", test::to_string(value)); +} + +/** + * Check the N_VALUES variable + */ +TEST(enumerationBuilderMacrosTest, n_values) +{ + ASSERT_EQ(test::N_VALUES_TestCustomEnum, test::NUMBER_OF_ELEMENTS); +} + +/** + * Construct enumeration of type TestCustomEnum from a string. + * + * CASES: + * x each element inside + * - string not in enumeration + */ +TEST(enumerationBuilderMacrosTest, from_string) +{ + // x each element inside + for (int i = 0; i < test::N_VALUES_TestCustomEnum; i++) + { + test::TestCustomEnum value = test::from_string_TestCustomEnum(test::string_values[i]); + ASSERT_TRUE(value == test::enum_values[i]); + } + + // string not in enumeration + ASSERT_THROW(test::from_string_TestCustomEnum("el_0"), eprosima::ddsrouter::utils::InitializationException); +} + +/** + * Compare to_string with expected result + * + * CASES: + * x each element inside + */ +TEST(enumerationBuilderMacrosTest, to_string) +{ + // x each element inside + for (int i = 0; i < test::N_VALUES_TestCustomEnum; i++) + { + ASSERT_EQ(test::to_string(test::enum_values[i]), test::string_values[i]); + } +} + +/** + * Compare serializator method of each value of enumeration + * + * CASES: + * x each element inside + */ +TEST(enumerationBuilderMacrosTest, serializator) +{ + // x each element inside + for (int i = 0; i < test::N_VALUES_TestCustomEnum; i++) + { + std::stringstream ss; + ss << test::enum_values[i]; + ASSERT_EQ(ss.str(), test::string_values[i]); + } +} + +int main( + int argc, + char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/ddsrouter_utils/test/unittest/macros/macrosTest.cpp b/ddsrouter_utils/test/unittest/macros/macrosTest.cpp new file mode 100644 index 000000000..c1b92c843 --- /dev/null +++ b/ddsrouter_utils/test/unittest/macros/macrosTest.cpp @@ -0,0 +1,66 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include + +/** + * Test \c STRINGIFY macro + * + * Cases: + * random string + * variable name + */ +TEST(macrosTest, stringify) +{ + // random string + { + ASSERT_EQ( + std::string(STRINGIFY(abcdefghijkl)), + std::string("abcdefghijkl") + ); + + ASSERT_EQ( + std::string(STRINGIFY(k1)), + std::string("k1") + ); + } + + // variable name + { + // Integer + int _random_value = 0; + ASSERT_EQ( + std::string(STRINGIFY(_random_value)), + std::string("_random_value") + ); + + // String + std::string _random_string = "other value"; + ASSERT_EQ( + std::string(STRINGIFY(_random_string)), + std::string("_random_string") + ); + } +} + +int main( + int argc, + char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/ddsrouter_utils/test/unittest/macros/recursiveMacrosTest.cpp b/ddsrouter_utils/test/unittest/macros/recursiveMacrosTest.cpp new file mode 100644 index 000000000..b9afe412b --- /dev/null +++ b/ddsrouter_utils/test/unittest/macros/recursiveMacrosTest.cpp @@ -0,0 +1,126 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include +#include + +/** + * Test \c COUNT_ARGUMENTS macro + * + * Cases: + * 0 + * 1 + * 5 + * 9 + */ +TEST(recursiveMacrosTest, count_arguments) +{ + // 0 + { + ASSERT_EQ( + 0, + COUNT_ARGUMENTS() + ); + } + + // 1 + { + ASSERT_EQ( + 1, + COUNT_ARGUMENTS( + "el1" + ) + ); + } + + // 5 + { + ASSERT_EQ( + 5, + COUNT_ARGUMENTS( + "el1", "el2", "el3", "el4", "el5" + ) + ); + } + + // 9 + { + ASSERT_EQ( + 9, + COUNT_ARGUMENTS( + "el1", "el2", "el3", "el4", "el5", + "el1", "el2", "el3", "el4" + ) + ); + } +} + +/** + * Test \c APPLY_MACRO_FOR_EACH macro + * + * Cases: + * addition + * string concatenation + */ +TEST(recursiveMacrosTest, apply_macro_for_each) +{ + +#define ADD_1(x) x += 1; + + // addition + { + int x = 1; + int y = 2; + int z = 3; + + APPLY_MACRO_FOR_EACH( + ADD_1, + x, + y, + z + ); + + ASSERT_EQ(x, 2); + ASSERT_EQ(y, 3); + ASSERT_EQ(z, 4); + } + +#define TO_LOWERCASE(x) eprosima::ddsrouter::utils::to_lowercase(x); + + // string concatenation + { + std::string hello = "HELLO"; + std::string bye = "ByE"; + + APPLY_MACRO_FOR_EACH( + TO_LOWERCASE, + hello, + bye + ); + + ASSERT_EQ(hello, "hello"); + ASSERT_EQ(bye, "bye"); + } +} + +int main( + int argc, + char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/ddsrouter_yaml/include/ddsrouter_yaml/impl/YamlReader.ipp b/ddsrouter_yaml/include/ddsrouter_yaml/impl/YamlReader.ipp index 046fc95a2..f1d91a1e4 100644 --- a/ddsrouter_yaml/include/ddsrouter_yaml/impl/YamlReader.ipp +++ b/ddsrouter_yaml/include/ddsrouter_yaml/impl/YamlReader.ipp @@ -21,7 +21,7 @@ #define _DDSROUTERYAML_IMPL_YAMLREADER_IPP_ #include -#include +#include #include namespace eprosima {