Skip to content

Commit

Permalink
Improve mapping between enum value and designation ECFLOW-1931
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosbento authored Dec 8, 2023
2 parents 7d4b289 + 88e9f3e commit ab34d71
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 303 deletions.
8 changes: 4 additions & 4 deletions ACore/src/ecflow/core/Converter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct bad_conversion : public std::runtime_error
explicit bad_conversion(const std::string& m) : std::runtime_error(m) {}
};

namespace details {
namespace detail {

template <typename To, typename From>
inline static auto try_lexical_convert(From&& v) {
Expand All @@ -36,12 +36,12 @@ inline static auto try_lexical_convert(From&& v) {
}
}

} // namespace details
} // namespace detail

template <typename From, typename To>
struct converter_traits
{
inline static auto convert(From&& v) { return details::try_lexical_convert<To>(std::forward<From>(v)); }
inline static auto convert(From&& v) { return detail::try_lexical_convert<To>(std::forward<From>(v)); }
};

template <>
Expand All @@ -64,7 +64,7 @@ struct converter_traits<From, std::enable_if<std::is_integral_v<From> || std::is

template <typename To, typename From>
inline auto convert_to(From&& v) {
using namespace ecf::details;
using namespace ecf::detail;
return converter_traits<From, To>::convert(std::forward<From>(v));
}

Expand Down
124 changes: 124 additions & 0 deletions ACore/src/ecflow/core/Enumerate.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright 2009- ECMWF.
*
* This software is licensed under the terms of the Apache Licence version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
* In applying this licence, ECMWF does not waive the privileges and immunities
* granted to it by virtue of its status as an intergovernmental organisation
* nor does it submit to any jurisdiction.
*/

#ifndef ecflow_core_Enumerate_HPP
#define ecflow_core_Enumerate_HPP

#include <optional>
#include <string>

#include <string_view>

namespace ecf {

namespace detail {

/**
* EnumTraits defines the mapping between a set of enum values and their designation.
*
* EnumTraits must define:
* - the mapping `map`, provided as an std::array composes of an std::pair<E, const char *> for each enum value
* - the `size`, holding the number os entries in `map`
*
* @tparam E
*/

template <typename E>
struct EnumTraits
{
};

} // namespace detail

template <typename E, typename TRAITS = detail::EnumTraits<E>>
struct Enumerate
{
public:
using enum_t = E;
using string_t = std::string_view;

/**
* Convert the given enum value to its designation
*
* @param e the enum value
* @return the designation, in case it exists; an empty optional, otherwise
*/
static constexpr inline std::optional<string_t> to_string(enum_t e) noexcept {
auto found = std::find_if(
std::begin(TRAITS::map), std::end(TRAITS::map), [&](const auto& item) { return item.first == e; });
if (found == std::end(TRAITS::map)) {
return std::nullopt;
}
return std::make_optional(found->second);
}

/**
* Convert the given designation to the related enum value
*
* @param s the designation
* @return the enum value, in case it exists; an empty optional, otherwise
*/
static constexpr inline std::optional<E> to_enum(string_t s) noexcept {
auto found = std::find_if(
std::begin(TRAITS::map), std::end(TRAITS::map), [&](const auto& item) { return item.second == s; });
if (found == std::end(TRAITS::map)) {
return std::nullopt;
}
return std::make_optional(found->first);
}

/**
* Checks if the given designation is valid (i.e. has a related enum value)
*
* @param s the designation
* @return true, if valid; false, otherwise
*/
static bool inline is_valid(string_t s) {
auto found = std::find_if(
std::begin(TRAITS::map), std::end(TRAITS::map), [&](const auto& item) { return item.second == s; });
return found != std::end(TRAITS::map);
}

/**
* The number of mapped enum values
*/
static const size_t size = TRAITS::size;

/**
* The vector of mapped enum values
*/
static auto enums() {
std::vector<E> result;
result.reserve(TRAITS::size);
std::transform(std::begin(TRAITS::map),
std::end(TRAITS::map),
std::back_inserter(result),
[](const auto& item) { return item.first; });
return result;
}

/**
* The vector of mapped designations
*/
static auto designations() {
std::vector<std::string> result;
result.reserve(TRAITS::size);
std::transform(std::begin(TRAITS::map),
std::end(TRAITS::map),
std::back_inserter(result),
[](const auto& item) { return item.second; });

return result;
}
};

} // namespace ecf

#endif /* ecflow_core_Enumerate_HPP */
Loading

0 comments on commit ab34d71

Please sign in to comment.