diff --git a/src/common/util/include/openvino/util/cpp_version.hpp b/src/common/util/include/openvino/util/cpp_version.hpp new file mode 100644 index 00000000000000..c0998588027c2a --- /dev/null +++ b/src/common/util/include/openvino/util/cpp_version.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2018-2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once +/** + * @brief Define a separate value for every version of C++ standard upto currently supported by build setup. + */ +#if !(defined(_MSC_VER) && __cplusplus == 199711L) +# if __cplusplus >= 201103L +# define OPENVINO_CPP_VER_AT_LEAST_11 +# if __cplusplus >= 201402L +# define OPENVINO_CPP_VER_AT_LEAST_14 +# if __cplusplus >= 201703L +# define OPENVINO_CPP_VER_AT_LEAST_17 +# if __cplusplus >= 202002L +# define OPENVINO_CPP_VER_AT_LEAST_20 +# endif +# endif +# endif +# endif +#elif defined(_MSC_VER) && __cplusplus == 199711L +# if _MSVC_LANG >= 201103L +# define OPENVINO_CPP_VER_AT_LEAST_11 +# if _MSVC_LANG >= 201402L +# define OPENVINO_CPP_VER_AT_LEAST_14 +# if _MSVC_LANG >= 201703L +# define OPENVINO_CPP_VER_AT_LEAST_17 +# if _MSVC_LANG >= 202002L +# define OPENVINO_CPP_VER_AT_LEAST_20 +# endif +# endif +# endif +# endif +#endif diff --git a/src/common/util/include/openvino/util/file_path.hpp b/src/common/util/include/openvino/util/file_path.hpp new file mode 100644 index 00000000000000..9080ea5289a51e --- /dev/null +++ b/src/common/util/include/openvino/util/file_path.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2018-2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include "openvino/util/filesystem.hpp" +namespace ov { +namespace util { + +#if defined(OPENVINO_HAS_FILESYSTEM) +using Path = std::filesystem::path; +#elif defined(OPENVINO_HAS_EXP_FILESYSTEM) +// Known issues: +// * error C2280: 'std::u32string std::experimental::filesystem::v1::path::u32string(void) const': attempting to +// * filesystem error: Cannot convert character sequence: Invalid in or incomplete multibyte or wide character + +/// +/// @typedef Path +/// @brief Alias for std::experimental::filesystem::path. +/// +/// This alias is used to simplify the usage of filesystem paths. +/// +/// @note The experimental version of std::filesystem::path may not support all features correctly. +/// It is recommended to use this alias with caution and consider upgrading to C++17 or higher +/// for full support of std::filesystem::path. +/// +using Path = std::experimental::filesystem::path; +#endif + +} // namespace util +} // namespace ov diff --git a/src/common/util/include/openvino/util/filesystem.hpp b/src/common/util/include/openvino/util/filesystem.hpp index c95869b4a7c73d..3ff5be2e29996e 100644 --- a/src/common/util/include/openvino/util/filesystem.hpp +++ b/src/common/util/include/openvino/util/filesystem.hpp @@ -4,28 +4,28 @@ #pragma once -#include "openvino/core/visibility.hpp" +#include "openvino/util/cpp_version.hpp" -#if defined(_MSC_VER) && defined(OPENVINO_CPP_VER_11) +#if defined(_MSC_VER) && defined(OPENVINO_CPP_VER_AT_LEAST_17) +# define OPENVINO_HAS_FILESYSTEM +#elif defined(_MSC_VER) && defined(OPENVINO_CPP_VER_AT_LEAST_11) # define OPENVINO_HAS_EXP_FILESYSTEM # define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING # define _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_FILESYSTEM #elif defined(__has_include) -# if defined(OPENVINO_CPP_VER_17) && (__has_include()) && (!__has_include()) +# if defined(OPENVINO_CPP_VER_AT_LEAST_17) && (__has_include()) # define OPENVINO_HAS_FILESYSTEM -# elif defined(OPENVINO_CPP_VER_11) && (__has_include()) +# elif defined(OPENVINO_CPP_VER_AT_LEAST_11) && (__has_include()) # define OPENVINO_HAS_EXP_FILESYSTEM # define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING # define _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_FILESYSTEM # endif #endif -#if !defined(OPENVINO_HAS_FILESYSTEM) && !defined(OPENVINO_HAS_EXP_FILESYSTEM) -# error "Neither #include nor #include is available." -#elif defined(OPENVINO_HAS_FILESYSTEM) +#if defined(OPENVINO_HAS_FILESYSTEM) # include -namespace std_fs = std::filesystem; #elif defined(OPENVINO_HAS_EXP_FILESYSTEM) # include -namespace std_fs = std::experimental::filesystem; +#else +# error "Neither #include nor #include is available." #endif diff --git a/src/core/include/openvino/core/graph_util.hpp b/src/core/include/openvino/core/graph_util.hpp index 3b5362f553715e..9a98b7c4fce427 100644 --- a/src/core/include/openvino/core/graph_util.hpp +++ b/src/core/include/openvino/core/graph_util.hpp @@ -21,7 +21,7 @@ #include "openvino/op/parameter.hpp" #include "openvino/pass/serialize.hpp" -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 # include #endif @@ -299,7 +299,7 @@ void serialize(const std::shared_ptr& m, const std::string& bin_path = "", ov::pass::Serialize::Version version = ov::pass::Serialize::Version::UNSPECIFIED); -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> void serialize(const std::shared_ptr& m, const Path& xml_path, @@ -327,7 +327,7 @@ void save_model(const std::shared_ptr& model, bool compress_to_fp16 = true); #endif -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> void save_model(const std::shared_ptr& model, const Path& output_model, bool compress_to_fp16 = true) { save_model(model, output_model.string(), compress_to_fp16); diff --git a/src/core/include/openvino/core/visibility.hpp b/src/core/include/openvino/core/visibility.hpp index 732a90d3d98b9c..2e8f6490a41c59 100644 --- a/src/core/include/openvino/core/visibility.hpp +++ b/src/core/include/openvino/core/visibility.hpp @@ -80,26 +80,26 @@ #if !(defined(_MSC_VER) && __cplusplus == 199711L) # if __cplusplus >= 201103L -# define OPENVINO_CPP_VER_11 +# define OPENVINO_CPP_VER_AT_LEAST_11 # if __cplusplus >= 201402L -# define OPENVINO_CPP_VER_14 +# define OPENVINO_CPP_VER_AT_LEAST_14 # if __cplusplus >= 201703L -# define OPENVINO_CPP_VER_17 +# define OPENVINO_CPP_VER_AT_LEAST_17 # if __cplusplus >= 202002L -# define OPENVINO_CPP_VER_20 +# define OPENVINO_CPP_VER_AT_LEAST_20 # endif # endif # endif # endif #elif defined(_MSC_VER) && __cplusplus == 199711L # if _MSVC_LANG >= 201103L -# define OPENVINO_CPP_VER_11 +# define OPENVINO_CPP_VER_AT_LEAST_11 # if _MSVC_LANG >= 201402L -# define OPENVINO_CPP_VER_14 +# define OPENVINO_CPP_VER_AT_LEAST_14 # if _MSVC_LANG >= 201703L -# define OPENVINO_CPP_VER_17 +# define OPENVINO_CPP_VER_AT_LEAST_17 # if _MSVC_LANG >= 202002L -# define OPENVINO_CPP_VER_20 +# define OPENVINO_CPP_VER_AT_LEAST_20 # endif # endif # endif diff --git a/src/core/include/openvino/pass/serialize.hpp b/src/core/include/openvino/pass/serialize.hpp index 22456662fd61ce..f7b3c2d0122ee3 100644 --- a/src/core/include/openvino/pass/serialize.hpp +++ b/src/core/include/openvino/pass/serialize.hpp @@ -11,7 +11,7 @@ #include "openvino/opsets/opset.hpp" #include "openvino/pass/pass.hpp" -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 # include #endif @@ -39,7 +39,7 @@ class OPENVINO_API Serialize : public ov::pass::ModelPass { Serialize(const std::string& xmlPath, const std::string& binPath, Version version = Version::UNSPECIFIED); -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 Serialize(const std::filesystem::path& xmlPath, const std::filesystem::path& binPath, Version version = Version::UNSPECIFIED) diff --git a/src/core/tests/file_util.cpp b/src/core/tests/file_util.cpp index b1b5381aab62b9..33d5d7f9db2896 100644 --- a/src/core/tests/file_util.cpp +++ b/src/core/tests/file_util.cpp @@ -11,6 +11,8 @@ #include #include +#include "openvino/util/file_path.hpp" + using namespace std; using namespace ov; @@ -167,3 +169,303 @@ TEST_F(TrimFileTest, relatice_path_to_source_forward_slash_always_supported) { auto str_ptr = ov::util::trim_file_name(file_path.c_str()); EXPECT_EQ(exp_path, str_ptr); } + +TEST(file_util, path_cast) { + // from char to char + EXPECT_STREQ("", ov::util::Path("").string().c_str()); + EXPECT_STREQ("file.txt", ov::util::Path("file.txt").string().c_str()); + EXPECT_STREQ("./local/file.txt", ov::util::Path("./local/file.txt").generic_string().c_str()); + EXPECT_STREQ("~/local/file.txt", ov::util::Path("~/local/file.txt").generic_string().c_str()); + EXPECT_STREQ("/usr/local/file.txt", ov::util::Path("/usr/local/file.txt").generic_string().c_str()); + EXPECT_STREQ("C:\\Users\\file.txt", ov::util::Path("C:\\Users\\file.txt").string().c_str()); + + // from char8_t to char + EXPECT_STREQ("", ov::util::Path(u8"").string().c_str()); + EXPECT_STREQ("file.txt", ov::util::Path(u8"file.txt").string().c_str()); + EXPECT_STREQ("./local/file.txt", ov::util::Path(u8"./local/file.txt").generic_string().c_str()); + EXPECT_STREQ("~/local/file.txt", ov::util::Path(u8"~/local/file.txt").generic_string().c_str()); + EXPECT_STREQ("/usr/local/file.txt", ov::util::Path(u8"/usr/local/file.txt").generic_string().c_str()); + + // from char16_t to char + EXPECT_STREQ("", ov::util::Path(u"").string().c_str()); + EXPECT_STREQ("file.txt", ov::util::Path(u"file.txt").string().c_str()); + EXPECT_STREQ("./local/file.txt", ov::util::Path(u"./local/file.txt").generic_string().c_str()); + EXPECT_STREQ("~/local/file.txt", ov::util::Path(u"~/local/file.txt").generic_string().c_str()); + EXPECT_STREQ("/usr/local/file.txt", ov::util::Path(u"/usr/local/file.txt").generic_string().c_str()); + + // from char32_t to char + EXPECT_STREQ("", ov::util::Path(U"").string().c_str()); + EXPECT_STREQ("file.txt", ov::util::Path(U"file.txt").string().c_str()); + EXPECT_STREQ("./local/file.txt", ov::util::Path(U"./local/file.txt").generic_string().c_str()); + EXPECT_STREQ("~/local/file.txt", ov::util::Path(U"~/local/file.txt").generic_string().c_str()); + EXPECT_STREQ("/usr/local/file.txt", ov::util::Path(U"/usr/local/file.txt").generic_string().c_str()); + + // from char to wchar_t + EXPECT_STREQ(L"", ov::util::Path("").wstring().c_str()); + EXPECT_STREQ(L"file.txt", ov::util::Path("file.txt").wstring().c_str()); + EXPECT_STREQ(L"./local/file.txt", ov::util::Path("./local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"~/local/file.txt", ov::util::Path("~/local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"/usr/local/file.txt", ov::util::Path("/usr/local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"C:\\Users\\file.txt", ov::util::Path("C:\\Users\\file.txt").wstring().c_str()); + + // from char8_t to wchar_t + EXPECT_STREQ(L"", ov::util::Path(u8"").wstring().c_str()); + EXPECT_STREQ(L"file.txt", ov::util::Path(u8"file.txt").wstring().c_str()); + EXPECT_STREQ(L"./local/file.txt", ov::util::Path(u8"./local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"~/local/file.txt", ov::util::Path(u8"~/local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"/usr/local/file.txt", ov::util::Path(u8"/usr/local/file.txt").generic_wstring().c_str()); + + // from char16_t to wchar_t + EXPECT_STREQ(L"", ov::util::Path(u"").wstring().c_str()); + EXPECT_STREQ(L"file.txt", ov::util::Path(u"file.txt").wstring().c_str()); + EXPECT_STREQ(L"./local/file.txt", ov::util::Path(u"./local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"~/local/file.txt", ov::util::Path(u"~/local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"/usr/local/file.txt", ov::util::Path(u"/usr/local/file.txt").generic_wstring().c_str()); + + // from char32_t to wchar_t + EXPECT_STREQ(L"", ov::util::Path(U"").wstring().c_str()); + EXPECT_STREQ(L"file.txt", ov::util::Path(U"file.txt").wstring().c_str()); + EXPECT_STREQ(L"./local/file.txt", ov::util::Path(U"./local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"~/local/file.txt", ov::util::Path(U"~/local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"/usr/local/file.txt", ov::util::Path(U"/usr/local/file.txt").generic_wstring().c_str()); + + // from char to u16string + EXPECT_TRUE(std::u16string(u"") == ov::util::Path("").u16string()); + EXPECT_TRUE(std::u16string(u"file.txt") == ov::util::Path("file.txt").u16string()); + EXPECT_TRUE(std::u16string(u"./local/file.txt") == ov::util::Path("./local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"~/local/file.txt") == ov::util::Path("~/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"/usr/local/file.txt") == ov::util::Path("/usr/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"C:\\Users\\file.txt") == ov::util::Path("C:\\Users\\file.txt").u16string()); + + // from char8_t to u16string + EXPECT_TRUE(std::u16string(u"") == ov::util::Path(u8"").u16string()); + EXPECT_TRUE(std::u16string(u"file.txt") == ov::util::Path(u8"file.txt").u16string()); + EXPECT_TRUE(std::u16string(u"./local/file.txt") == ov::util::Path(u8"./local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"~/local/file.txt") == ov::util::Path(u8"~/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"/usr/local/file.txt") == ov::util::Path(u8"/usr/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"C:\\Users\\file.txt") == ov::util::Path(u8"C:\\Users\\file.txt").u16string()); + + // from char16_t to u16string + EXPECT_TRUE(std::u16string(u"") == ov::util::Path(u"").u16string()); + EXPECT_TRUE(std::u16string(u"file.txt") == ov::util::Path(u"file.txt").u16string()); + EXPECT_TRUE(std::u16string(u"./local/file.txt") == ov::util::Path(u"./local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"~/local/file.txt") == ov::util::Path(u"~/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"/usr/local/file.txt") == ov::util::Path(u"/usr/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"C:\\Users\\file.txt") == ov::util::Path(u"C:\\Users\\file.txt").u16string()); + + // from char32_t to u16string + EXPECT_TRUE(std::u16string(u"") == ov::util::Path(U"").u16string()); + EXPECT_TRUE(std::u16string(u"file.txt") == ov::util::Path(U"file.txt").u16string()); + EXPECT_TRUE(std::u16string(u"./local/file.txt") == ov::util::Path(U"./local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"~/local/file.txt") == ov::util::Path(U"~/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"/usr/local/file.txt") == ov::util::Path(U"/usr/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"C:\\Users\\file.txt") == ov::util::Path(U"C:\\Users\\file.txt").u16string()); +} + +// There are known issues related with usage of std::filesystem::path unocode represenataion: +// https://jira.devtools.intel.com/browse/CVS-160477 +// * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95048 +// * https://stackoverflow.com/questions/58521857/cross-platform-way-to-handle-stdstring-stdwstring-with-stdfilesystempath +#if !defined(__GNUC__) || (__GNUC__ > 12 || __GNUC__ == 12 && __GNUC_MINOR__ >= 3) +# define GCC_NOT_USED_OR_VER_AT_LEAST_12_3 +#endif + +#if !defined(__clang__) || defined(__clang__) && __clang_major__ >= 17 +# define CLANG_NOT_USED_OR_VER_AT_LEAST_17 +#endif + +TEST(file_util, path_cast_unicode) { + EXPECT_EQ("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗1.txt", ov::util::Path("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗1.txt").generic_string()); + EXPECT_TRUE(std::u16string(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗6.txt") == + ov::util::Path(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗6.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗7.txt") == + ov::util::Path(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗7.txt").generic_u16string()); + +#if !defined(_MSC_VER) && defined(OPENVINO_CPP_VER_AT_LEAST_20) + EXPECT_TRUE(std::u8string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗9.txt") == + ov::util::Path("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗9.txt").generic_u8string()); +#endif +#if defined(OPENVINO_CPP_VER_AT_LEAST_20) + EXPECT_TRUE(std::u8string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗10.txt") == + ov::util::Path(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗10.txt").generic_u8string()); + EXPECT_TRUE(std::u8string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗11.txt") == + ov::util::Path(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗11.txt").generic_u8string()); + EXPECT_TRUE(std::u8string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗12.txt") == + ov::util::Path(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗12.txt").generic_u8string()); +#elif defined(OPENVINO_CPP_VER_AT_LEAST_17) + EXPECT_EQ(std::string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗14.txt"), + ov::util::Path(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗14.txt").generic_u8string()); + EXPECT_EQ(std::string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗15.txt"), + ov::util::Path(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗15.txt").generic_u8string()); +#endif + +#if !defined(_MSC_VER) || defined(_MSC_VER) && defined(OPENVINO_CPP_VER_AT_LEAST_20) + EXPECT_TRUE(std::u16string(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗8.txt") == + ov::util::Path(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗8.txt").generic_u16string()); + EXPECT_TRUE(std::u32string(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗18.txt") == + ov::util::Path(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗18.txt").u32string()); +#endif + +#if defined(OPENVINO_CPP_VER_AT_LEAST_20) && \ + (defined(_MSC_VER) || \ + !defined(_MSC_VER) && defined(GCC_NOT_USED_OR_VER_AT_LEAST_12_3) && defined(CLANG_NOT_USED_OR_VER_AT_LEAST_17)) + EXPECT_TRUE(std::u8string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗16.txt") == + ov::util::Path(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗16.txt").generic_u8string()); + EXPECT_TRUE(std::wstring(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗29.txt") == + ov::util::Path(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗29.txt").wstring()); +#endif +} + +#if !defined(_MSC_VER) +TEST(file_util, path_cast_unicode_from_string) { + EXPECT_TRUE(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗13.txt" == + ov::util::Path("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗13.txt").generic_u8string()); + EXPECT_TRUE(std::u16string(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗5.txt") == + ov::util::Path("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗5.txt").generic_u16string()); + EXPECT_TRUE(std::u32string(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗21.txt") == + ov::util::Path("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗21.txt").u32string()); +} + +TEST(file_util, path_cast_unicode_to_string) { + EXPECT_EQ(std::string("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗4.txt"), + ov::util::Path(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗4.txt").generic_string()); + EXPECT_EQ(std::string("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗2.txt"), + ov::util::Path(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗2.txt").generic_string()); + EXPECT_EQ(std::string("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗3.txt"), + ov::util::Path(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗3.txt").generic_string()); +} +#endif + +#if !defined(_MSC_VER) && defined(GCC_NOT_USED_OR_VER_AT_LEAST_12_3) && defined(CLANG_NOT_USED_OR_VER_AT_LEAST_17) +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95048 +// https://stackoverflow.com/questions/58521857/cross-platform-way-to-handle-stdstring-stdwstring-with-stdfilesystempath + +TEST(file_util, path_cast_unicode_from_string_to_wstring) { + EXPECT_TRUE(std::wstring(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗27.txt") == + ov::util::Path("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗27.txt").generic_wstring()); +} +TEST(file_util, path_cast_unicode_from_wstring_to_string) { + EXPECT_STREQ("~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗25.txt", + ov::util::Path(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗25.txt").generic_string().c_str()); +} +#endif + +TEST(file_util, path_cast_to_u32string) { + // from char to u32string + EXPECT_TRUE(std::u32string(U"") == ov::util::Path("").u32string()); + EXPECT_TRUE(std::u32string(U"file.txt") == ov::util::Path("file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"./local/file.txt") == ov::util::Path("./local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"~/local/file.txt") == ov::util::Path("~/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"/usr/local/file.txt") == ov::util::Path("/usr/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"C:\\Users\\file.txt") == ov::util::Path("C:\\Users\\file.txt").u32string()); + + // from char8_t to u32string + EXPECT_TRUE(std::u32string(U"") == ov::util::Path(u8"").u32string()); + EXPECT_TRUE(std::u32string(U"file.txt") == ov::util::Path(u8"file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"./local/file.txt") == ov::util::Path(u8"./local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"~/local/file.txt") == ov::util::Path(u8"~/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"/usr/local/file.txt") == ov::util::Path(u8"/usr/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"C:\\Users\\file.txt") == ov::util::Path(u8"C:\\Users\\file.txt").u32string()); + + // from char16_t to u32string + EXPECT_TRUE(std::u32string(U"") == ov::util::Path(u"").u32string()); + EXPECT_TRUE(std::u32string(U"file.txt") == ov::util::Path(u"file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"./local/file.txt") == ov::util::Path(u"./local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"~/local/file.txt") == ov::util::Path(u"~/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"/usr/local/file.txt") == ov::util::Path(u"/usr/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"C:\\Users\\file.txt") == ov::util::Path(u"C:\\Users\\file.txt").u32string()); + + // from char32_t to u32string + EXPECT_TRUE(std::u32string(U"") == ov::util::Path(U"").u32string()); + EXPECT_TRUE(std::u32string(U"file.txt") == ov::util::Path(U"file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"./local/file.txt") == ov::util::Path(U"./local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"~/local/file.txt") == ov::util::Path(U"~/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"/usr/local/file.txt") == ov::util::Path(U"/usr/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"C:\\Users\\file.txt") == ov::util::Path(U"C:\\Users\\file.txt").u32string()); + + // from char16_t, char32_t to u32string + EXPECT_TRUE(std::u32string(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗23.txt") == + ov::util::Path(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗23.txt").u32string()); + EXPECT_TRUE(std::u32string(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗24.txt") == + ov::util::Path(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗24.txt").u32string()); +} + +#if defined(GCC_NOT_USED_OR_VER_AT_LEAST_12_3) && defined(CLANG_NOT_USED_OR_VER_AT_LEAST_17) +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95048 +// https://stackoverflow.com/questions/58521857/cross-platform-way-to-handle-stdstring-stdwstring-with-stdfilesystempath + +TEST(file_util, path_cast_from_wstring) { + // from wchar_t to char + EXPECT_STREQ("", ov::util::Path(L"").string().c_str()); + EXPECT_STREQ("file.txt", ov::util::Path(L"file.txt").string().c_str()); + EXPECT_STREQ("./local/file.txt", ov::util::Path(L"./local/file.txt").generic_string().c_str()); + EXPECT_STREQ("~/local/file.txt", ov::util::Path(L"~/local/file.txt").generic_string().c_str()); + EXPECT_STREQ("/usr/local/file.txt", ov::util::Path(L"/usr/local/file.txt").generic_string().c_str()); + + // from wchar_t to wchar_t + EXPECT_STREQ(L"", ov::util::Path(L"").wstring().c_str()); + EXPECT_STREQ(L"file.txt", ov::util::Path(L"file.txt").wstring().c_str()); + EXPECT_STREQ(L"./local/file.txt", ov::util::Path(L"./local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"~/local/file.txt", ov::util::Path(L"~/local/file.txt").generic_wstring().c_str()); + EXPECT_STREQ(L"/usr/local/file.txt", ov::util::Path(L"/usr/local/file.txt").generic_wstring().c_str()); + + // from wchar_t to char16_t + EXPECT_TRUE(std::u16string(u"") == ov::util::Path(L"").u16string()); + EXPECT_TRUE(std::u16string(u"file.txt") == ov::util::Path(L"file.txt").u16string()); + EXPECT_TRUE(std::u16string(u"./local/file.txt") == ov::util::Path(L"./local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"~/local/file.txt") == ov::util::Path(L"~/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"/usr/local/file.txt") == ov::util::Path(L"/usr/local/file.txt").generic_u16string()); + EXPECT_TRUE(std::u16string(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗26.txt") == + ov::util::Path(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗26.txt").generic_u16string()); +} + +TEST(file_util, path_cast_to_wstring) { + // from char16_t, char32_t to wchar_t + EXPECT_STREQ(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗28.txt", + ov::util::Path(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗28.txt").generic_wstring().c_str()); + + EXPECT_STREQ(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗30.txt", + ov::util::Path(u"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗30.txt").wstring().c_str()); +} + +TEST(file_util, path_cast_from_wstring_to_u32string) { + EXPECT_TRUE(std::u32string(U"") == ov::util::Path(L"").u32string()); + EXPECT_TRUE(std::u32string(U"file.txt") == ov::util::Path(L"file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"./local/file.txt") == ov::util::Path(L"./local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"~/local/file.txt") == ov::util::Path(L"~/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"/usr/local/file.txt") == ov::util::Path(L"/usr/local/file.txt").u32string()); + EXPECT_TRUE(std::u32string(U"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗31.txt") == + ov::util::Path(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗31.txt").u32string()); +} +#endif + +TEST(file_util, path_cast_from_wstring_to_char8_t) { + // from wchar_t to char8_t +#if defined(OPENVINO_CPP_VER_AT_LEAST_20) + EXPECT_TRUE(std::u8string(u8"") == ov::util::Path(L"").u8string()); + EXPECT_TRUE(std::u8string(u8"file.txt") == ov::util::Path(L"file.txt").u8string()); + EXPECT_TRUE(std::u8string(u8"./local/file.txt") == ov::util::Path(L"./local/file.txt").generic_u8string()); + EXPECT_TRUE(std::u8string(u8"~/local/file.txt") == ov::util::Path(L"~/local/file.txt").generic_u8string()); + EXPECT_TRUE(std::u8string(u8"/usr/local/file.txt") == ov::util::Path(L"/usr/local/file.txt").generic_u8string()); +#elif defined(OPENVINO_CPP_VER_AT_LEAST_17) + EXPECT_EQ(std::string(""), ov::util::Path(L"").u8string()); + EXPECT_EQ(std::string("file.txt"), ov::util::Path(L"file.txt").u8string()); + EXPECT_EQ(std::string("./local/file.txt"), ov::util::Path(L"./local/file.txt").generic_u8string()); + EXPECT_EQ(std::string("~/local/file.txt"), ov::util::Path(L"~/local/file.txt").generic_u8string()); + EXPECT_EQ(std::string("/usr/local/file.txt"), ov::util::Path(L"/usr/local/file.txt").generic_u8string()); +#endif +} + +TEST(file_util, unicode_path_cast_from_wstring_to_char8_t) { + // from wchar_t to char8_t +#if defined(OPENVINO_CPP_VER_AT_LEAST_20) && defined(GCC_NOT_USED_OR_VER_AT_LEAST_12_3) && \ + defined(CLANG_NOT_USED_OR_VER_AT_LEAST_17) + EXPECT_TRUE(std::u8string(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗32.txt") == + ov::util::Path(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗32.txt").generic_u8string()); + +#elif defined(OPENVINO_CPP_VER_AT_LEAST_17) && defined(GCC_NOT_USED_OR_VER_AT_LEAST_12_3) && \ + defined(CLANG_NOT_USED_OR_VER_AT_LEAST_17) + EXPECT_EQ(u8"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗33.txt", + ov::util::Path(L"~/狗/ǡ୫ԩϗ/にほ/ąę/ど/௸ඊƷ/狗33.txt").generic_u8string()); +#endif +} diff --git a/src/core/tests/frontend/frontend_manager.cpp b/src/core/tests/frontend/frontend_manager.cpp index 589ba4224dc4cc..c81af32cb12b1a 100644 --- a/src/core/tests/frontend/frontend_manager.cpp +++ b/src/core/tests/frontend/frontend_manager.cpp @@ -480,7 +480,7 @@ TEST(FrontEndManagerTest, Exception_Safety_Input_Model_set_tensor_partial_value) CHECK_EXCEPTION_INPUT_MODEL(input_model->set_tensor_partial_value({}, {}, {})) } -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 TEST(FrontEndManagerTest, testFEMDestroy_InputModelHolderUsingPath) { InputModel::Ptr input_model; diff --git a/src/core/tests/pass/serialization/deterministicity.cpp b/src/core/tests/pass/serialization/deterministicity.cpp index efd2457461f552..c6ac7f58a02492 100644 --- a/src/core/tests/pass/serialization/deterministicity.cpp +++ b/src/core/tests/pass/serialization/deterministicity.cpp @@ -296,7 +296,7 @@ TEST_P(SerializationDeterministicityInputOutputTest, FromIrModel) { EXPECT_TRUE(files_equal(xml_2, xml_1)); } -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 TEST_P(SerializationDeterministicityInputOutputTest, FromOvModelBybPath) { auto irVersion = GetParam(); diff --git a/src/core/tests/pass/serialization/serialize.cpp b/src/core/tests/pass/serialization/serialize.cpp index 944c9829a517d4..46185f6f2704b4 100644 --- a/src/core/tests/pass/serialization/serialize.cpp +++ b/src/core/tests/pass/serialization/serialize.cpp @@ -74,7 +74,7 @@ TEST_P(SerializationTest, SaveModel) { }); } -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 TEST_P(SerializationTest, CompareFunctionsByPath) { const auto out_xml_path = std::filesystem::path(m_out_xml_path); const auto out_bin_path = std::filesystem::path(m_out_bin_path); diff --git a/src/frontends/common/include/openvino/frontend/frontend.hpp b/src/frontends/common/include/openvino/frontend/frontend.hpp index 4667620f1a2f16..578d978c6c4c43 100644 --- a/src/frontends/common/include/openvino/frontend/frontend.hpp +++ b/src/frontends/common/include/openvino/frontend/frontend.hpp @@ -15,7 +15,7 @@ #include "openvino/frontend/input_model.hpp" #include "openvino/frontend/visibility.hpp" -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 # include #endif @@ -54,7 +54,7 @@ class FRONTEND_API FrontEnd { /// \return true if model recognized, false - otherwise. template inline bool supported(const Types&... vars) const { -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 if constexpr ((std::is_same_v || ...)) { return supported_impl({path_as_str_or_forward(vars)...}); } else @@ -74,7 +74,7 @@ class FRONTEND_API FrontEnd { /// \return Loaded input model. template inline InputModel::Ptr load(const Types&... vars) const { -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 if constexpr ((std::is_same_v || ...)) { return load_impl({path_as_str_or_forward(vars)...}); } else @@ -135,7 +135,7 @@ class FRONTEND_API FrontEnd { /// \{ void add_extension(const std::string& library_path); -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 void add_extension(const std::filesystem::path& library_path) { add_extension(library_path.string()); } @@ -185,7 +185,7 @@ class FRONTEND_API FrontEnd { static std::shared_ptr create_copy(const std::shared_ptr& ov_model, const std::shared_ptr& shared_object); -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template static constexpr auto path_as_str_or_forward(T&& p) { if constexpr (std::is_same_v>) { diff --git a/src/frontends/tests/frontend/shared/src/conversion.cpp b/src/frontends/tests/frontend/shared/src/conversion.cpp index 058d5534965436..1a545b92708d76 100644 --- a/src/frontends/tests/frontend/shared/src/conversion.cpp +++ b/src/frontends/tests/frontend/shared/src/conversion.cpp @@ -96,7 +96,7 @@ TEST_P(FrontEndConversionExtensionTest, TestConversionExtensionViaSO) { ASSERT_NE(model, nullptr); } -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 TEST_P(FrontEndConversionExtensionTest, TestConversionExtensionViaSOByPath) { auto frontend = m_param.m_frontend; const std::filesystem::path lib_path = get_lib_path("test_builtin_extensions"); diff --git a/src/inference/include/openvino/runtime/core.hpp b/src/inference/include/openvino/runtime/core.hpp index 9234b8cc6232af..16379fb7b198bd 100644 --- a/src/inference/include/openvino/runtime/core.hpp +++ b/src/inference/include/openvino/runtime/core.hpp @@ -25,7 +25,7 @@ #include "openvino/runtime/remote_context.hpp" #include "openvino/runtime/tensor.hpp" -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 # include #endif @@ -109,7 +109,7 @@ class OPENVINO_RUNTIME_API Core { const std::string& bin_path = {}, const ov::AnyMap& properties = {}) const; -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> auto read_model(const Path& model_path, const Path& bin_path = {}, const ov::AnyMap& properties = {}) const { return read_model(model_path.string(), bin_path.string(), properties); @@ -141,7 +141,7 @@ class OPENVINO_RUNTIME_API Core { return read_model(model_path, bin_path, AnyMap{std::forward(properties)...}); } -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template && (sizeof...(Properties) > 0)>* = nullptr> @@ -250,7 +250,7 @@ class OPENVINO_RUNTIME_API Core { */ CompiledModel compile_model(const std::string& model_path, const AnyMap& properties = {}); -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> auto compile_model(const Path& model_path, const AnyMap& properties = {}) const { return compile_model(model_path.string(), properties); @@ -283,7 +283,7 @@ class OPENVINO_RUNTIME_API Core { return compile_model(model_path, AnyMap{std::forward(properties)...}); } -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> auto compile_model(const Path& model_path, Properties&&... properties) { return compile_model(model_path.string(), std::forward(properties)...); @@ -317,7 +317,7 @@ class OPENVINO_RUNTIME_API Core { const std::string& device_name, const AnyMap& properties = {}); -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> auto compile_model(const Path& model_path, const std::string& device_name, const AnyMap& properties = {}) { return compile_model(model_path.string(), device_name, properties); @@ -353,7 +353,7 @@ class OPENVINO_RUNTIME_API Core { return compile_model(model_path, device_name, AnyMap{std::forward(properties)...}); } -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> auto compile_model(const Path& model_path, const std::string& device_name, Properties&&... properties) { return compile_model(model_path.string(), device_name, std::forward(properties)...); @@ -444,7 +444,7 @@ class OPENVINO_RUNTIME_API Core { */ void add_extension(const std::string& library_path); -#ifdef OPENVINO_CPP_VER_17 +#ifdef OPENVINO_CPP_VER_AT_LEAST_17 template >* = nullptr> void add_extension(const Path& model_path) { add_extension(model_path.string()); diff --git a/src/inference/tests/functional/ov_core_test.cpp b/src/inference/tests/functional/ov_core_test.cpp index 6bdfaadb777059..ea0a7621a8cdf3 100644 --- a/src/inference/tests/functional/ov_core_test.cpp +++ b/src/inference/tests/functional/ov_core_test.cpp @@ -114,7 +114,7 @@ TEST_F(CoreBaseTest, LoadOVFolderOverCWPathPluginXML) { #endif -#if defined(OPENVINO_CPP_VER_17) && defined(ENABLE_OV_IR_FRONTEND) +#if defined(OPENVINO_CPP_VER_AT_LEAST_17) && defined(ENABLE_OV_IR_FRONTEND) namespace ov::test { TEST_F(CoreBaseTest, read_model_with_std_fs_path) { generate_test_model_files("test-model"); diff --git a/src/inference/tests/functional/ov_extension_test.cpp b/src/inference/tests/functional/ov_extension_test.cpp index 66b618c0854ebf..0ef5cf33253921 100644 --- a/src/inference/tests/functional/ov_extension_test.cpp +++ b/src/inference/tests/functional/ov_extension_test.cpp @@ -82,7 +82,7 @@ class CustomReLU : public ov::op::Op { }; #if defined(ENABLE_OV_IR_FRONTEND) -# ifdef OPENVINO_CPP_VER_17 +# ifdef OPENVINO_CPP_VER_AT_LEAST_17 TEST_F(OVExtensionTests, ReshapeIRWithNewExtensionsPathLib) { core.add_extension(std::filesystem::path(getOVExtensionPath())); test();