Skip to content

Commit

Permalink
Merge pull request #252 from JeffersonLab/nbrei_issue132
Browse files Browse the repository at this point in the history
JParameterManager gives clean error messages for unsupported types (Addresses issue #132)
  • Loading branch information
nathanwbrei authored Oct 10, 2023
2 parents d11801b + 1abda35 commit b351322
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
38 changes: 33 additions & 5 deletions src/libraries/JANA/Services/JParameterManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,25 @@ inline T JParameterManager::RegisterParameter(std::string name, const T default_
}


/// @brief Logic for parsing different types in a generic way
#if __cplusplus >= 201703L
/// @brief Basic implementation of Parse for C++17 and newer. Provides a helpful error message when attempting to parse a type that doesn't come with a stream operator.
template <typename T>
void JParameterManager::Parse(const std::string& value, T& val) {
std::stringstream ss(value);
ss >> val;
void JParameterManager::Parse(const std::string& s, T& out) {
constexpr bool parseable = JTypeInfo::is_parseable<T>::value;
static_assert(parseable, "Type is not automatically parseable by JParameterManager. To use, provide a template specialization for JParameterManager::Parse(std::string in, T& out).");
if constexpr (parseable) {
std::stringstream ss(s);
ss >> out;
}
}
#else
/// @brief Basic implementation of Parse for C++14 and earlier.
template <typename T>
void JParameterManager::Parse(const std::string& s, T& out) {
std::stringstream ss(s);
ss >> out;
}
#endif


/// @brief Specialization for string.
Expand Down Expand Up @@ -360,13 +373,28 @@ inline void JParameterManager::Parse(const std::string& value, std::vector<T> &v
}
}

/// @brief Logic for stringifying different types in a generic way
#if __cplusplus >= 201703L
/// @brief Basic implementation of Stringify for C++17 and newer. Provides a helpful error message when attempting to stringify a type that doesn't come with a stream operator.
template <typename T>
inline std::string JParameterManager::Stringify(const T& value) {
constexpr bool serializable = JTypeInfo::is_serializable<T>::value;
static_assert(serializable, "Type is not automatically serializable by JParameterManager. To use, provide a template specialization for JParameterManager::Stringify(const T& val) -> std::string.");
if constexpr (serializable) {
std::stringstream ss;
ss << value;
return ss.str();
}
}
#else
/// @brief Basic implementation of Parse for C++14 and earlier.
template <typename T>
inline std::string JParameterManager::Stringify(const T& value) {
std::stringstream ss;
ss << value;
return ss.str();
}
#endif


template <>
inline std::string JParameterManager::Stringify(const float& value) {
Expand Down
14 changes: 14 additions & 0 deletions src/libraries/JANA/Utils/JTypeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@

namespace JTypeInfo {


template <typename, typename=void>
struct is_parseable : std::false_type {};

template <typename T>
struct is_parseable<T, std::void_t<decltype(std::declval<std::istream>() >> std::declval<T&>())>> : std::true_type {};

template <typename, typename=void>
struct is_serializable : std::false_type {};

template <typename T>
struct is_serializable<T, std::void_t<decltype(std::declval<std::ostream>() << std::declval<T>())>> : std::true_type {};


template<typename T>
std::string demangle(void) {

Expand Down
15 changes: 15 additions & 0 deletions src/programs/tests/JParameterManagerTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,18 @@ TEST_CASE("JParameterManager_Issue217StringsWithWhitespace") {
}


enum class Mood {Good, Bad, Mediocre};
TEST_CASE("JParameterManager_CompileTimeErrorForParseAndStringify") {

int x;
JParameterManager::Parse("22", x);
Mood m;
// Uncomment these to test compile-time error message
//JParameterManager::Parse("Mediocre", m);
//JParameterManager::Stringify(m);
}





0 comments on commit b351322

Please sign in to comment.