Skip to content

Commit

Permalink
Build Enumeration Dev Utils (#17)
Browse files Browse the repository at this point in the history
* Implement dev-utils Build Enumeration

Signed-off-by: jparisu <[email protected]>

* Add vector to custom enumeration builder

Signed-off-by: jparisu <[email protected]>

* Add fixes to enumeration builder

Signed-off-by: jparisu <[email protected]>

* apply suggestions

Signed-off-by: jparisu <[email protected]>

* remove ... in file path

Signed-off-by: jparisu <[email protected]>

Signed-off-by: jparisu <[email protected]>
  • Loading branch information
jparisu authored Nov 30, 2022
1 parent f97515a commit dd327d3
Show file tree
Hide file tree
Showing 4 changed files with 372 additions and 37 deletions.
73 changes: 36 additions & 37 deletions cpp_utils/include/cpp_utils/macros/custom_enumeration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ namespace utils {
/**
* @brief This macro creates a Custom Enumeration with auxiliary functions and variables.
*
* An enumeration built with ENUEMERATION_BUILDER has:
* An enumeration built with ENUMERATION_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_<enumeration_name> with the names of each element of the enumeration
* - array called \c NAMES_<enumeration_name> 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_<enumeration_name> method that gives enumeration value from string name.
Expand All @@ -55,42 +55,41 @@ namespace utils {
* 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<std::string, COUNT_ARGUMENTS(__VA_ARGS__)> names_ ## enumeration_name = \
{ APPLY_MACRO_FOR_EACH(STRINGIFY_WITH_COMMA, __VA_ARGS__) }; \
\
/* To string method */ \
inline const std::string& to_string(const enumeration_name& e) \
{ return names_ ## enumeration_name[static_cast<int>(e)]; } \
\
inline std::vector<std::string> string_vector_ ## enumeration_name() \
{ return std::vector<std::string> (names_ ## enumeration_name.begin(), names_ ## enumeration_name.end()); } \
\
/* From string */ \
inline 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<enumeration_name>(i); \
throw eprosima::utils::InitializationException( \
STR_ENTRY << "Not correct name " << s << " for Enum " << STRINGIFY(enumeration_name) << "."); \
} \
\
/* Serialization operation */ \
inline std::ostream& operator <<(std::ostream& os, const enumeration_name& e) \
{ os << to_string(e); return os; } \
\
/* Number of elements in enumeration */ \
#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<std::string, COUNT_ARGUMENTS(__VA_ARGS__)> NAMES_ ## enumeration_name = \
{ APPLY_MACRO_FOR_EACH(STRINGIFY_WITH_COMMA, __VA_ARGS__) }; \
\
/* To string method */ \
inline const std::string& to_string(const enumeration_name& e) \
{ return NAMES_ ## enumeration_name[static_cast<int>(e)]; } \
\
inline std::vector<std::string> string_vector_ ## enumeration_name() \
{ return std::vector<std::string> (NAMES_ ## enumeration_name.begin(), NAMES_ ## enumeration_name.end()); } \
\
/* From string */ \
inline 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<enumeration_name>(i); \
throw eprosima::utils::InitializationException( \
STR_ENTRY << "Not correct name " << s << " for Enum " << STRINGIFY(enumeration_name) << "."); \
} \
\
/* Serialization operation */ \
inline 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 eprosima */
14 changes: 14 additions & 0 deletions dev_utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# eProsima Developers Utils Module

This is a package that contains certain scripts to help in the implementation of new projects.
These scripts are meant to generate code or certain utils in a fast and optimal way.

> :warning: This is not a linkable package, it is only for utils focus on developing faster or better code.
## Automatic Code Generator

These tools are meant to autogenerate general code in different languages.

### Enumeration builder

Extend in a new file the whole `ENUMERATION_BUILDER` macro.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# ENUMERATION BUILDER

This auto generates the code that would be generated by macro `ENUMERATION_BUILDER` in
`dev-utils/cpp_utils/include/cpp_utils/macros/custom_enumeration.hpp`.

## Motivation

This script is useful because the use of this macro could have problems depending on its use and/or architecture:

- Windows does extend macros in a different order.
- SWIG does not create classes or enums that are extended from a macro.

## Usage

This is a standalone script. In order to execute it:

```sh
python3 enumeration_builder.py --output include/output.hpp --enum CustomEnum --values "value1;value2" --namespaces "eprosima;utils"
```
Loading

0 comments on commit dd327d3

Please sign in to comment.