Skip to content

Conversation

jmarrec
Copy link
Contributor

@jmarrec jmarrec commented May 5, 2023

Comment on lines +50 to +59
// C++14
template <class T> using remove_cv_t = typename std::remove_cv<T>::type;

template <class T> using remove_reference_t = typename std::remove_reference<T>::type;

// C++20
template <class T> struct remove_cvref {
using type = remove_cv_t<remove_reference_t<T>>;
};
template <class T> using remove_cvref_t = typename remove_cvref<T>::type;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backport some helpers to be in C++11 for readability

Comment on lines +21 to +23
#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
#include <filesystem>
#endif // CLI11_HAS_FILESYSTEM
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conditional import

Comment on lines +92 to +104
template <typename T, typename Enable = void> struct is_path : std::false_type {};
template <typename T, typename Enable = void> struct force_widen : std::false_type {};

#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
template <typename T>
struct is_path<T, typename std::enable_if<std::is_same<std::filesystem::path, remove_cvref_t<T>>::value>::type>
: std::true_type {};
#if _WIN32
template <typename T> struct force_widen<T, enable_if_t<is_path<T>::value>> : std::true_type {};
#endif
#else
template <typename T> struct is_path : std::false_type {};
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Detect if T is a path, exists even if isn't used. I'm using remove_cvref, but that may not be necessary (but it doesn't hurt much)

if WIN32 => force_widen

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote it this way so force_widen could be extended to other types later if needed.

Comment on lines +642 to +645
struct classify_object<
T,
typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
std::is_assignable<T &, std::string>::value && !force_widen<T>::value>::type> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here basically, I make it so that an object, in the event that it is both assignable and/or constructible from std::string AND from std::wstring, will be classified as wstring_assignable / wstring_constructible (the wide one) if it's force_widen

@@ -69,7 +69,7 @@ set(CLI11_MULTIONLY_TESTS TimerTest)
find_package(Catch2 CONFIG)

if(Catch2_FOUND)
if(NOT TARGET Catch2::Catch2)
if(NOT (TARGET Catch2::Catch2 OR TARGET Catch2::Catch2WithMain))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated: I tried to build with Catch2 v3, hit this error. Then I hit another one and gave up (later it's trying to add_sources to catch_main whcih is just an ALIAS in the case it's v3).

Comment on lines +24 to +26
#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
#include <filesystem>
#endif // CLI11_HAS_FILESYSTEM
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conditional import in test

Comment on lines +1315 to +1352
#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
static_assert(!CLI::is_path<float>::value, "float shouldn't be a path");
static_assert(!CLI::is_path<std::string>::value, "string shouldn't be a path");

static_assert(CLI::is_path<std::filesystem::path>::value, "path should be a path");
static_assert(CLI::is_path<const std::filesystem::path>::value, "const path should be a path");
static_assert(CLI::is_path<std::filesystem::path &>::value, "path& should be a path");
static_assert(CLI::is_path<const std::filesystem::path &>::value, "const path& should be a path");

#if _WIN32
static_assert(CLI::detail::classify_object<std::filesystem::path>::value ==
CLI::detail::object_category::wstring_assignable,
"path is not classified as wstring_assignable on WIN32");
static_assert(CLI::force_widen<std::filesystem::path>::value, "path should be force_widen on WIN32");
static_assert(CLI::force_widen<const std::filesystem::path>::value, "const path should be force_widen on WIN32");
static_assert(CLI::force_widen<std::filesystem::path &>::value, "path& should be force_widen on WIN32");
static_assert(CLI::force_widen<const std::filesystem::path &>::value, "const path& should be force_widen on WIN32");
#else
static_assert(CLI::detail::classify_object<std::filesystem::path>::value ==
CLI::detail::object_category::string_assignable,
"path is not classified as string_assignable");

static_assert(!CLI::force_widen<std::filesystem::path>::value, "path should not be force_widen");
static_assert(!CLI::force_widen<const std::filesystem::path>::value, "const path should not be force_widen");
static_assert(!CLI::force_widen<std::filesystem::path &>::value, "path& should not be force_widen");
static_assert(!CLI::force_widen<const std::filesystem::path &>::value, "const path& should not be force_widen");
#endif

TEST_CASE("Types: LexicalConversionPath", "[helpers]") {
CLI::results_t input = {"TéstFileNotUsed.txt"};
std::filesystem::path x;
bool res = CLI::detail::lexical_conversion<decltype(x), decltype(x)>(input, x);
CHECK(res);
CHECK(CLI::to_path("TéstFileNotUsed.txt").native() == x.native());
}

#endif // CLI11_HAS_FILESYSTEM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conditional testing: lots of static_assert to make sure it's behaving correctly, and an actual runtime test that fails before, works now.

@phlptp
Copy link
Collaborator

phlptp commented Jun 15, 2023

this issue was resolved by #876, if there are unresolved issues from that please feel free to resubmit.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unicode support: automatically widen on windows when option is assigned a std::filesystem::path
2 participants