Skip to content

Commit e1447b3

Browse files
authored
Enumeration Builder (#289)
* Refactor and addition to macros Signed-off-by: jparisu <javierparis@eprosima.com> * Implementation of ENUMERATION_BUILDER Signed-off-by: jparisu <javierparis@eprosima.com> * Fix windows compilation Signed-off-by: jparisu <javierparis@eprosima.com> * Add preprocessor to windows compilation Signed-off-by: jparisu <javierparis@eprosima.com> * Fix windows compilation external link Signed-off-by: jparisu <javierparis@eprosima.com> * Fix windows compilation 2019 WSDK Signed-off-by: jparisu <javierparis@eprosima.com> * apply suggestions Signed-off-by: jparisu <javierparis@eprosima.com> * uncrustify Signed-off-by: jparisu <javierparis@eprosima.com> Signed-off-by: jparisu <javierparis@eprosima.com>
1 parent 8d635a8 commit e1447b3

16 files changed

Lines changed: 751 additions & 8 deletions

File tree

.github/actions/install-router-subpackage-windows/action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
name: Install DDS Router subpackages
22
description: Install and setup DDS Router subpackages for linking and building application in Windows
33
inputs:
4+
cmake_extra_args:
5+
description: 'Specifies cmake arguments different from default'
6+
required: false
7+
default: ' '
48
cmake_build_type:
59
description: 'Specifies the build type on single-configuration generators'
610
required: true
@@ -17,6 +21,7 @@ runs:
1721
- run: >
1822
cmake -DCMAKE_PREFIX_PATH='C:\Program Files\gtest;C:\Program Files\yamlcpp;C:\Program Files;${{ github.workspace }}\..\fastdds\install' `
1923
-DCMAKE_CXX_FLAGS="/WX /EHsc" -DBUILD_TOOL_TESTS=ON -DBUILD_LIBRARY_TESTS=ON `
24+
${{ inputs.cmake_extra_args }} `
2025
-B build\${{ inputs.subpackage }} -A x64 -T host=x64 DDS-Router/${{ inputs.subpackage_dir }};
2126
cmake --build build\${{ inputs.subpackage }} --config ${{ inputs.cmake_build_type }} --target install;
2227

.github/workflows/test.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,17 @@ jobs:
102102
subpackage: ddsrouter_cmake
103103
subpackage_dir: ddsrouter_cmake
104104

105+
# This is needed for windows 2019 to use /Zc:preprocessor to use c++ std preprocessor for ENUMERATION_BUILDER
106+
# due to a windows 2019 SDK non bug
107+
- name: Set environment variables for Windows 2019 build
108+
run: |
109+
echo ("W2019_CMAKE_EXTRA_ARGS=-DCMAKE_SYSTEM_VERSION=10.0.19041.0") >> $env:GITHUB_ENV
110+
if: contains( matrix.windows-version , '2019')
111+
105112
- name: Install ddsrouter_utils
106113
uses: ./DDS-Router/.github/actions/install-router-subpackage-windows
107114
with:
115+
cmake_extra_args: ${{ env.W2019_CMAKE_EXTRA_ARGS }}
108116
cmake_build_type: ${{ matrix.cmake-config }}
109117
subpackage: ddsrouter_utils
110118
subpackage_dir: ddsrouter_utils

ddsrouter_cmake/cmake/cpp_common/configure_project_cpp.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ macro(configure_project_cpp)
5757
activate_code_coverage()
5858
endif()
5959

60+
# Set custom C++ Flags
61+
custom_cpp_flags()
62+
6063
# Finish macro
6164
message(STATUS "C++ Project ${MODULE_NAME_LARGE} configured.")
6265

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
###############################################################################
16+
# CMake Build Type
17+
###############################################################################
18+
19+
# Set custom CMAKE_CXX_FLAGS
20+
macro(custom_cpp_flags)
21+
22+
# Only for windows
23+
if(MSVC OR MSVC_IDE)
24+
# Set standard preprocessor
25+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:preprocessor")
26+
endif()
27+
28+
endmacro()

ddsrouter_core/src/cpp/participant/implementations/auxiliar/BaseParticipant.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#ifndef __SRC_DDSROUTERCORE_PARTICIPANT_IMPLEMENTATIONS_AUXILIAR_BASEPARTICIPANT_HPP_
2020
#define __SRC_DDSROUTERCORE_PARTICIPANT_IMPLEMENTATIONS_AUXILIAR_BASEPARTICIPANT_HPP_
2121

22-
#include <ddsrouter_utils/macros.hpp>
22+
#include <ddsrouter_utils/macros/macros.hpp>
2323

2424
#include <ddsrouter_core/configuration/participant/ParticipantConfiguration.hpp>
2525

ddsrouter_utils/include/ddsrouter_utils/Log.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// Use FastDDS log
2323
#include <fastdds/dds/log/Log.hpp>
2424

25-
#include <ddsrouter_utils/macros.hpp>
25+
#include <ddsrouter_utils/macros/macros.hpp>
2626

2727
namespace eprosima {
2828
namespace ddsrouter {
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* @file macros.hpp
17+
*
18+
* This file contains constant values common for the whole project
19+
*/
20+
21+
#ifndef _DDSROUTERUTILS_MACROS_CUSTOMENUMERATION_HPP_
22+
#define _DDSROUTERUTILS_MACROS_CUSTOMENUMERATION_HPP_
23+
24+
#include <string>
25+
#include <array>
26+
27+
#include <ddsrouter_utils/exception/InitializationException.hpp>
28+
#include <ddsrouter_utils/macros/macros.hpp>
29+
#include <ddsrouter_utils/macros/recursive_macros.hpp>
30+
31+
namespace eprosima {
32+
namespace ddsrouter {
33+
namespace utils {
34+
35+
/**
36+
* @brief This macro creates a Custom Enumeration with auxiliary functions and variables.
37+
*
38+
* An enumeration built with ENUEMERATION_BUILDER has:
39+
* - enum class with name \c enumeration_name and N values, one for each extra argument, and with that exact name.
40+
* - array called \c nammes_<enumeration_name> with the names of each element of the enumeration
41+
* as strings of the enum value.
42+
* - \c to_string method to get the string associated with an enumeration value.
43+
* - \c from_string_<enumeration_name> method that gives enumeration value from string name.
44+
* - operator << for each enumeration value using to_string .
45+
* - \c N_VALUES_<enumeration_name> unsigned int to get the number of elements in the enumeration.
46+
*
47+
* @arg enumeration_name it sets the enum class name and is used to name variables and methods.
48+
* @arg extra_arguments each of the elements of the enum class. Their conversion to string would use this same name.
49+
*
50+
* @note empty custom enumerations are not allowed, even when empty enum class are.
51+
*
52+
* @example
53+
* ENUMERATION_BUILDER(CustomEnum, el1, el2);
54+
* CustomEnum my_value = CustomEnum::el1; // Set my_value as el1 = 0
55+
* my_value = from_string_CustomEnum("el2"); // Set my_value as el2 = 1
56+
* to_string(my_value); // = "el2"
57+
*/
58+
#define ENUMERATION_BUILDER(enumeration_name, ...) \
59+
\
60+
/* Forbid empty enumerations */ \
61+
static_assert( COUNT_ARGUMENTS(__VA_ARGS__), "Empty Enumerations are not allowed."); \
62+
\
63+
/* Declare enumeration */ \
64+
enum class enumeration_name {__VA_ARGS__ \
65+
}; \
66+
\
67+
/* Initialize name arrays */ \
68+
const std::array<std::string, COUNT_ARGUMENTS(__VA_ARGS__)> names_ ## enumeration_name = \
69+
{ APPLY_MACRO_FOR_EACH(STRINGIFY_WITH_COMMA, __VA_ARGS__) }; \
70+
\
71+
/* To string method */ \
72+
const std::string& to_string(const enumeration_name& e) \
73+
{ return names_ ## enumeration_name[static_cast<int>(e)]; } \
74+
\
75+
/* From string */ \
76+
enumeration_name from_string_ ## enumeration_name(const std::string& s) \
77+
{ \
78+
for (int i = 0; i < COUNT_ARGUMENTS(__VA_ARGS__); i++) \
79+
if (names_ ## enumeration_name[i] == s)return static_cast<enumeration_name>(i); \
80+
throw eprosima::ddsrouter::utils::InitializationException( \
81+
STR_ENTRY << "Not correct name " << s << " for Enum " << STRINGIFY(enumeration_name) << "."); \
82+
} \
83+
\
84+
/* Serialization operation */ \
85+
std::ostream& operator <<(std::ostream& os, const enumeration_name& e) { os << to_string(e); return os; } \
86+
\
87+
/* Number of elements in enumeration */ \
88+
constexpr const unsigned int N_VALUES_ ## enumeration_name = COUNT_ARGUMENTS(__VA_ARGS__);
89+
90+
91+
} /* namespace utils */
92+
} /* namespace ddsrouter */
93+
} /* namespace eprosima */
94+
95+
#endif /* _DDSROUTERUTILS_MACROS_CUSTOMENUMERATION_HPP_ */

ddsrouter_utils/include/ddsrouter_utils/macros.hpp renamed to ddsrouter_utils/include/ddsrouter_utils/macros/macros.hpp

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,58 @@
1818
* This file contains constant values common for the whole project
1919
*/
2020

21-
#ifndef _DDSROUTERUTILS_MACROS_HPP_
22-
#define _DDSROUTERUTILS_MACROS_HPP_
21+
#ifndef _DDSROUTERUTILS_MACROS_MACROS_HPP_
22+
#define _DDSROUTERUTILS_MACROS_MACROS_HPP_
2323

2424
#include <type_traits>
2525

2626
namespace eprosima {
2727
namespace ddsrouter {
2828
namespace utils {
2929

30+
/////////////////////////
31+
// FORMAT
32+
/////////////////////////
33+
34+
/**
35+
* @brief Get string of the argument passed to the macro
36+
*
37+
* @example
38+
* STRINGIFY(value) = "value"
39+
*/
3040
#define STRINGIFY(x) #x
3141

42+
//! Same as \c STRINGIFY but adding a comma "," at the end
43+
#define STRINGIFY_WITH_COMMA(x) #x,
44+
45+
46+
/////////////////////////
47+
// TYPES
48+
/////////////////////////
49+
50+
/**
51+
* @brief Force the specialization type of a template to be a subclass of a Class.
52+
*
53+
* @example
54+
* FORCE_TEMPLATE_SUBCLASS(A, B) = static assert <=> B not inherit from A
55+
*
56+
* @param base parent class that \c derived must inherit.
57+
* @param derived specialization class.
58+
*/
3259
#define FORCE_TEMPLATE_SUBCLASS(base, derived) \
3360
static_assert(std::is_base_of<base, derived>::value, STRINGIFY(derived) " class not derived from " STRINGIFY(base))
3461

35-
// TODO: probably in the future is needed to create a utils method that transforms this name to a human reasonable name
62+
/**
63+
* @brief Get string of the name of the CPP Data Type of the argument
64+
*
65+
* @example
66+
* STRINGIFY(int) = "j"
67+
* STRINGIFY(string) = "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"
68+
*/
3669
#define TYPE_NAME(x) typeid(x).name()
3770

3871
} /* namespace utils */
3972
} /* namespace ddsrouter */
4073
} /* namespace eprosima */
4174

42-
#endif /* _DDSROUTERUTILS_MACROS_HPP_ */
75+
#endif /* _DDSROUTERUTILS_MACROS_MACROS_HPP_ */
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* @file recursive_macros.hpp
17+
*
18+
* This file contains constant values common for the whole project
19+
*/
20+
21+
#ifndef _DDSROUTERUTILS_MACROS_RECURSIVEMACROS_HPP_
22+
#define _DDSROUTERUTILS_MACROS_RECURSIVEMACROS_HPP_
23+
24+
#include <ddsrouter_utils/macros/macros.hpp>
25+
26+
namespace eprosima {
27+
namespace ddsrouter {
28+
namespace utils {
29+
30+
/////////////////////////
31+
// COUNT ARGUMENTS
32+
/////////////////////////
33+
34+
/**
35+
* @brief Get 11th macro.
36+
*
37+
* @note This macro is used in \c COUNT_ARGUMENT macro.
38+
*/
39+
#define _ELEVENTH_ARGUMENT(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) \
40+
a11
41+
42+
/**
43+
* @brief Count number of arguments in a variadic macro with maximum 9 variables
44+
*
45+
* @note This is an auxiliary macro that encapsulates the funtionality of \c COUNT_ARGUMENTS so that macro
46+
* could be changed to a higher value without breaking API.
47+
*
48+
* @note \c dummy value is required to non argument calls.
49+
*/
50+
#define _COUNT_ARGUMENTS__UP_TO_NINE(...) \
51+
_ELEVENTH_ARGUMENT(dummy, ## __VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
52+
53+
/**
54+
* @brief Count number of arguments in a variadic macro
55+
*
56+
* @warning This macro only allows up to 9 values.
57+
*
58+
* @note if more arguments required, change \c _ELEVENTH_ARGUMENT for a higher one.
59+
*
60+
* @example
61+
* COUNT_ARGUMENTS(el1, el2, el3) = 3
62+
*/
63+
#define COUNT_ARGUMENTS(...) \
64+
_COUNT_ARGUMENTS__UP_TO_NINE(__VA_ARGS__)
65+
66+
67+
/////////////////////////
68+
// FOR EACH
69+
/////////////////////////
70+
71+
/**
72+
* @brief These macros allow to create an iterative APPLY_MACRO_FOR_EACH loop over every argument.
73+
*
74+
* Each item of form \c _FE_N allow to evaluate the function \c ACTION for the next \c N arguments.
75+
*/
76+
#define _FE_1(ACTION, X) ACTION(X)
77+
#define _FE_2(ACTION, X, ...) ACTION(X) _FE_1(ACTION, __VA_ARGS__)
78+
#define _FE_3(ACTION, X, ...) ACTION(X) _FE_2(ACTION, __VA_ARGS__)
79+
#define _FE_4(ACTION, X, ...) ACTION(X) _FE_3(ACTION, __VA_ARGS__)
80+
#define _FE_5(ACTION, X, ...) ACTION(X) _FE_4(ACTION, __VA_ARGS__)
81+
#define _FE_6(ACTION, X, ...) ACTION(X) _FE_5(ACTION, __VA_ARGS__)
82+
#define _FE_7(ACTION, X, ...) ACTION(X) _FE_6(ACTION, __VA_ARGS__)
83+
#define _FE_8(ACTION, X, ...) ACTION(X) _FE_7(ACTION, __VA_ARGS__)
84+
#define _FE_9(ACTION, X, ...) ACTION(X) _FE_8(ACTION, __VA_ARGS__)
85+
//... repeat as needed
86+
87+
/**
88+
* @brief Get the 9th argument
89+
*
90+
* @note this is useful for \c APPLY_MACRO_FOR_EACH macro.
91+
*/
92+
#define _GET_NINTH_ARGUMENT(_1, _2, _3, _4, _5, _6, _7, _8, _9, NAME, ...) \
93+
NAME
94+
95+
#define _APPLY_MACRO_FOR_EACH__UP_TO_NINE(action, ...) \
96+
_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__)
97+
98+
/**
99+
* @brief Execute \c action (must be a macro) for every argument after it.
100+
*
101+
* @warning This macro only allows up to 9 values.
102+
*
103+
* @note if more arguments required, change \c _APPLY_MACRO_FOR_EACH__UP_TO_NINE for a higher one.
104+
*
105+
* @example
106+
* APPLY_MACRO_FOR_EACH(print, el1, el2, el3) => print(el1); print(el2); print(el3);
107+
*/
108+
#define APPLY_MACRO_FOR_EACH(action, ...) \
109+
_APPLY_MACRO_FOR_EACH__UP_TO_NINE(action, __VA_ARGS__)
110+
111+
} /* namespace utils */
112+
} /* namespace ddsrouter */
113+
} /* namespace eprosima */
114+
115+
#endif /* _DDSROUTERUTILS_MACROS_RECURSIVEMACROS_HPP_ */

ddsrouter_utils/include/ddsrouter_utils/utils.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include <string>
2828
#include <vector>
2929

30-
#include <ddsrouter_utils/macros.hpp>
30+
#include <ddsrouter_utils/macros/macros.hpp>
3131
#include <ddsrouter_utils/Formatter.hpp>
3232
#include <ddsrouter_utils/library/library_dll.h>
3333

0 commit comments

Comments
 (0)