Skip to content

Commit

Permalink
String conversions (#421)
Browse files Browse the repository at this point in the history
* add a variant of the string conversions for the default string operations.  Discriminate between the is_convertible and is_constructible type traits for object.

* update the test to test the different situations with the funny string like type
  • Loading branch information
phlptp authored Jan 31, 2020
1 parent 6b7f6a7 commit ee851c7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
15 changes: 12 additions & 3 deletions include/CLI/TypeTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,24 @@ template <typename S> class is_tuple_like {
};

/// Convert an object to a string (directly forward if this can become a string)
template <typename T, enable_if_t<std::is_constructible<std::string, T>::value, detail::enabler> = detail::dummy>
template <typename T, enable_if_t<std::is_convertible<T, std::string>::value, detail::enabler> = detail::dummy>
auto to_string(T &&value) -> decltype(std::forward<T>(value)) {
return std::forward<T>(value);
}

/// Construct a string from the object
template <typename T,
enable_if_t<std::is_constructible<std::string, T>::value && !std::is_convertible<T, std::string>::value,
detail::enabler> = detail::dummy>
std::string to_string(const T &value) {
return std::string(value);
}

/// Convert an object to a string (streaming must be supported for that type)
template <typename T,
enable_if_t<!std::is_constructible<std::string, T>::value && is_ostreamable<T>::value, detail::enabler> =
detail::dummy>
enable_if_t<!std::is_convertible<std::string, T>::value && !std::is_constructible<std::string, T>::value &&
is_ostreamable<T>::value,
detail::enabler> = detail::dummy>
std::string to_string(T &&value) {
std::stringstream stream;
stream << value;
Expand Down
21 changes: 21 additions & 0 deletions tests/AppTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1885,6 +1885,27 @@ TEST_F(TApp, VectorUnlimString) {
EXPECT_EQ(answer, strvec);
}

// From https://github.com/CLIUtils/CLI11/issues/420
TEST_F(TApp, stringLikeTests) {
struct nType {
explicit nType(const std::string &a_value) : m_value{a_value} {}

explicit operator std::string() const { return std::string{"op str"}; }

std::string m_value;
};

nType m_type{"abc"};
app.add_option("--type", m_type, "type")->capture_default_str();
run();

EXPECT_EQ(app["--type"]->as<std::string>(), "op str");
args = {"--type", "bca"};
run();
EXPECT_EQ(std::string(m_type), "op str");
EXPECT_EQ(m_type.m_value, "bca");
}

TEST_F(TApp, VectorExpectedRange) {
std::vector<std::string> strvec;

Expand Down

0 comments on commit ee851c7

Please sign in to comment.