diff --git a/Dev/Cpp/Effekseer/CMakeLists.txt b/Dev/Cpp/Effekseer/CMakeLists.txt index 7ef7a628b3..03f89b4633 100644 --- a/Dev/Cpp/Effekseer/CMakeLists.txt +++ b/Dev/Cpp/Effekseer/CMakeLists.txt @@ -25,6 +25,7 @@ set(effekseer_public_h Effekseer/Network/Effekseer.Server.h Effekseer/Network/Effekseer.Client.h Effekseer/Utils/Effekseer.CustomAllocator.h + Effekseer/Utils/String.h Effekseer/IO/Effekseer.EfkEfcFactory.h Effekseer/SIMD/Base.h diff --git a/Dev/Cpp/Effekseer/Effekseer/Backend/GraphicsDevice.h b/Dev/Cpp/Effekseer/Effekseer/Backend/GraphicsDevice.h index ebeabcb144..2b966f6b15 100644 --- a/Dev/Cpp/Effekseer/Effekseer/Backend/GraphicsDevice.h +++ b/Dev/Cpp/Effekseer/Effekseer/Backend/GraphicsDevice.h @@ -5,6 +5,7 @@ #include "../Effekseer.Base.Pre.h" #include "../Effekseer.Color.h" #include "../Utils/Effekseer.CustomAllocator.h" +#include "../Utils/String.h" #include #include #include diff --git a/Dev/Cpp/Effekseer/Effekseer/Effekseer.Base.h b/Dev/Cpp/Effekseer/Effekseer/Effekseer.Base.h index ebe621b560..0a32acd778 100644 --- a/Dev/Cpp/Effekseer/Effekseer/Effekseer.Base.h +++ b/Dev/Cpp/Effekseer/Effekseer/Effekseer.Base.h @@ -103,269 +103,6 @@ enum class BindType : int32_t Always = 2, }; -class StringHelper -{ -public: - template - static std::vector> Split(const std::basic_string& s, T delim) - { - std::vector> elems; - - size_t start = 0; - - for (size_t i = 0; i < s.size(); i++) - { - if (s[i] == delim) - { - elems.emplace_back(s.substr(start, i - start)); - start = i + 1; - } - } - - if (start == s.size()) - { - elems.emplace_back(std::basic_string()); - } - else - { - elems.emplace_back(s.substr(start, s.size() - start)); - } - - return elems; - } - - template - static std::basic_string Replace(std::basic_string target, std::basic_string from_, std::basic_string to_) - { - auto Pos = target.find(from_); - - while (Pos != std::basic_string::npos) - { - target.replace(Pos, from_.length(), to_); - Pos = target.find(from_, Pos + to_.length()); - } - - return target; - } - - template - static std::basic_string To(const U* str) - { - std::basic_string ret; - size_t len = 0; - while (str[len] != 0) - { - len++; - } - - ret.resize(len); - - for (size_t i = 0; i < len; i++) - { - ret[i] = static_cast(str[i]); - } - - return ret; - } - - template - static std::basic_string Join(const std::vector>& elems, std::basic_string separator) - { - std::basic_string ret; - - for (size_t i = 0; i < elems.size(); i++) - { - ret += elems[i]; - - if (i != elems.size() - 1) - { - ret += separator; - } - } - - return ret; - } -}; - -class PathHelper -{ -private: - template - static std::basic_string Normalize(const std::vector>& paths) - { - std::vector> elems; - - for (size_t i = 0; i < paths.size(); i++) - { - if (paths[i] == StringHelper::To("..")) - { - if (elems.size() > 0 && elems.back() != StringHelper::To("..")) - { - elems.pop_back(); - } - else - { - elems.push_back(StringHelper::To("..")); - } - } - else - { - elems.push_back(paths[i]); - } - } - - return StringHelper::Join(elems, StringHelper::To("/")); - } - -public: - template - static bool IsSeparator(T s) - { - return s == static_cast('/') || s == static_cast('\\'); - } - - template - static std::basic_string Normalize(const std::basic_string& path) - { - if (path.size() == 0) - return path; - - auto paths = - StringHelper::Split(StringHelper::Replace(path, StringHelper::To("\\"), StringHelper::To("/")), static_cast('/')); - - return Normalize(paths); - } - - template - static std::basic_string Relative(const std::basic_string& targetPath, const std::basic_string& basePath) - { - if (basePath.size() == 0 || targetPath.size() == 0) - { - return targetPath; - } - - auto targetPaths = StringHelper::Split(StringHelper::Replace(targetPath, StringHelper::To("\\"), StringHelper::To("/")), - static_cast('/')); - auto basePaths = - StringHelper::Split(StringHelper::Replace(basePath, StringHelper::To("\\"), StringHelper::To("/")), static_cast('/')); - - if (*(basePath.end() - 1) != static_cast('/') && *(basePath.end() - 1) != static_cast('\\')) - { - basePaths.pop_back(); - } - - int32_t offset = 0; - while (targetPaths.size() > offset && basePaths.size() > offset) - { - if (targetPaths[offset] == basePaths[offset]) - { - offset++; - } - else - { - break; - } - } - - std::basic_string ret; - - for (size_t i = offset; i < basePaths.size(); i++) - { - ret += StringHelper::To("../"); - } - - for (size_t i = offset; i < targetPaths.size(); i++) - { - ret += targetPaths[i]; - - if (i != targetPaths.size() - 1) - { - ret += StringHelper::To("/"); - } - } - - return ret; - } - - template - static std::basic_string Absolute(const std::basic_string& targetPath, const std::basic_string& basePath) - { - if (targetPath == StringHelper::To("")) - return StringHelper::To(""); - - if (basePath == StringHelper::To("")) - return targetPath; - - auto targetPaths = StringHelper::Split(StringHelper::Replace(targetPath, StringHelper::To("\\"), StringHelper::To("/")), - static_cast('/')); - auto basePaths = - StringHelper::Split(StringHelper::Replace(basePath, StringHelper::To("\\"), StringHelper::To("/")), static_cast('/')); - - if (*(basePath.end() - 1) != static_cast('/') && *(basePath.end() - 1) != static_cast('\\')) - { - basePaths.pop_back(); - } - - std::copy(targetPaths.begin(), targetPaths.end(), std::back_inserter(basePaths)); - - return Normalize(basePaths); - } - - template - static std::basic_string GetDirectoryName(const std::basic_string& path) - { - if (path == StringHelper::To("")) - return StringHelper::To(""); - - int last_separator = -1; - for (size_t i = 0; i < path.size(); i++) - { - if (IsSeparator(path[i])) - { - last_separator = i; - } - } - - if (last_separator >= 0) - { - return path.substr(0, last_separator + 1); - } - return StringHelper::To(""); - } - - template - static std::basic_string GetFilenameWithoutExt(const std::basic_string& path) - { - if (path == StringHelper::To("")) - return StringHelper::To(""); - - int last_separator = -1; - for (size_t i = 0; i < path.size(); i++) - { - if (IsSeparator(path[i])) - { - last_separator = i; - } - } - last_separator++; - - int last_dot = -1; - for (size_t i = last_separator; i < path.size(); i++) - { - if (path[i] == static_cast('.')) - { - last_dot = i; - } - } - - if (last_dot >= 0) - { - return path.substr(last_separator, last_dot - last_separator); - } - return path.substr(last_separator, path.size() - last_separator); - } -}; - } // namespace Effekseer #endif // __EFFEKSEER_BASE_H__ diff --git a/Dev/Cpp/Effekseer/Effekseer/Effekseer.ResourceManager.h b/Dev/Cpp/Effekseer/Effekseer/Effekseer.ResourceManager.h index f5ecf9c55d..c8080a5442 100644 --- a/Dev/Cpp/Effekseer/Effekseer/Effekseer.ResourceManager.h +++ b/Dev/Cpp/Effekseer/Effekseer/Effekseer.ResourceManager.h @@ -6,6 +6,7 @@ #include "Effekseer.Resource.h" #include "Model//ProceduralModelParameter.h" #include "Model/ProceduralModelGenerator.h" +#include "Utils/String.h" #include namespace Effekseer diff --git a/Dev/Cpp/Effekseer/Effekseer/Utils/Effekseer.CustomAllocator.h b/Dev/Cpp/Effekseer/Effekseer/Utils/Effekseer.CustomAllocator.h index 12880c6fbd..d2c93b15ef 100644 --- a/Dev/Cpp/Effekseer/Effekseer/Utils/Effekseer.CustomAllocator.h +++ b/Dev/Cpp/Effekseer/Effekseer/Utils/Effekseer.CustomAllocator.h @@ -216,90 +216,6 @@ using CustomUnorderedMap = std::unordered_map, class KeyEq = std::equal_to> using CustomAlignedUnorderedMap = std::unordered_map>>; -//---------------------------------------------------------------------------------- -// -//---------------------------------------------------------------------------------- -template -class StringView -{ - using Traits = std::char_traits; - -public: - StringView() - : ptr_(nullptr) - , size_(0) - { - } - - StringView(const T* ptr) - : ptr_(ptr) - , size_(Traits::length(ptr)) - { - } - - StringView(const T* ptr, size_t size) - : ptr_(ptr) - , size_(size) - { - } - - template - StringView(const T ptr[N]) - : ptr_(ptr) - , size_(N) - { - } - - StringView(const CustomString& str) - : ptr_(str.data()) - , size_(str.size()) - { - } - - const T* data() const - { - return ptr_; - } - - size_t size() const - { - return size_; - } - - bool operator==(const StringView& rhs) const - { - return size() == rhs.size() && Traits::compare(data(), rhs.data(), size()) == 0; - } - - bool operator!=(const StringView& rhs) const - { - return size() != rhs.size() || Traits::compare(data(), rhs.data(), size()) != 0; - } - - struct Hash - { - size_t operator()(const StringView& key) const - { - constexpr size_t basis = (sizeof(size_t) == 8) ? 14695981039346656037ULL : 2166136261U; - constexpr size_t prime = (sizeof(size_t) == 8) ? 1099511628211ULL : 16777619U; - - const uint8_t* data = reinterpret_cast(key.data()); - size_t count = key.size() * sizeof(T); - size_t val = basis; - for (size_t i = 0; i < count; i++) - { - val ^= static_cast(data[i]); - val *= prime; - } - return val; - } - }; - -private: - const T* ptr_; - size_t size_; -}; - } // namespace Effekseer #endif // __EFFEKSEER_BASE_PRE_H__ \ No newline at end of file diff --git a/Dev/Cpp/Effekseer/Effekseer/Utils/String.h b/Dev/Cpp/Effekseer/Effekseer/Utils/String.h new file mode 100644 index 0000000000..fd57ad0215 --- /dev/null +++ b/Dev/Cpp/Effekseer/Effekseer/Utils/String.h @@ -0,0 +1,357 @@ +#ifndef __EFFEKSEER_STRING_H__ +#define __EFFEKSEER_STRING_H__ + +#include +#include +#include + +namespace Effekseer +{ + +template +class StringView +{ + using Traits = std::char_traits; + +public: + StringView() + : ptr_(nullptr) + , size_(0) + { + } + + StringView(const T* ptr) + : ptr_(ptr) + , size_(Traits::length(ptr)) + { + } + + StringView(const T* ptr, size_t size) + : ptr_(ptr) + , size_(size) + { + } + + template + StringView(const T ptr[N]) + : ptr_(ptr) + , size_(N) + { + } + + StringView(const CustomString& str) + : ptr_(str.data()) + , size_(str.size()) + { + } + + const T* data() const + { + return ptr_; + } + + size_t size() const + { + return size_; + } + + bool operator==(const StringView& rhs) const + { + return size() == rhs.size() && Traits::compare(data(), rhs.data(), size()) == 0; + } + + bool operator!=(const StringView& rhs) const + { + return size() != rhs.size() || Traits::compare(data(), rhs.data(), size()) != 0; + } + + struct Hash + { + size_t operator()(const StringView& key) const + { + constexpr size_t basis = (sizeof(size_t) == 8) ? 14695981039346656037ULL : 2166136261U; + constexpr size_t prime = (sizeof(size_t) == 8) ? 1099511628211ULL : 16777619U; + + const uint8_t* data = reinterpret_cast(key.data()); + size_t count = key.size() * sizeof(T); + size_t val = basis; + for (size_t i = 0; i < count; i++) + { + val ^= static_cast(data[i]); + val *= prime; + } + return val; + } + }; + +private: + const T* ptr_; + size_t size_; +}; + +class StringHelper +{ +public: + template + static std::vector> Split(const std::basic_string& s, T delim) + { + std::vector> elems; + + size_t start = 0; + + for (size_t i = 0; i < s.size(); i++) + { + if (s[i] == delim) + { + elems.emplace_back(s.substr(start, i - start)); + start = i + 1; + } + } + + if (start == s.size()) + { + elems.emplace_back(std::basic_string()); + } + else + { + elems.emplace_back(s.substr(start, s.size() - start)); + } + + return elems; + } + + template + static std::basic_string Replace(std::basic_string target, std::basic_string from_, std::basic_string to_) + { + auto Pos = target.find(from_); + + while (Pos != std::basic_string::npos) + { + target.replace(Pos, from_.length(), to_); + Pos = target.find(from_, Pos + to_.length()); + } + + return target; + } + + template + static std::basic_string To(const U* str) + { + std::basic_string ret; + size_t len = 0; + while (str[len] != 0) + { + len++; + } + + ret.resize(len); + + for (size_t i = 0; i < len; i++) + { + ret[i] = static_cast(str[i]); + } + + return ret; + } + + template + static std::basic_string Join(const std::vector>& elems, std::basic_string separator) + { + std::basic_string ret; + + for (size_t i = 0; i < elems.size(); i++) + { + ret += elems[i]; + + if (i != elems.size() - 1) + { + ret += separator; + } + } + + return ret; + } +}; + +class PathHelper +{ +private: + template + static std::basic_string Normalize(const std::vector>& paths) + { + std::vector> elems; + + for (size_t i = 0; i < paths.size(); i++) + { + if (paths[i] == StringHelper::To("..")) + { + if (elems.size() > 0 && elems.back() != StringHelper::To("..")) + { + elems.pop_back(); + } + else + { + elems.push_back(StringHelper::To("..")); + } + } + else + { + elems.push_back(paths[i]); + } + } + + return StringHelper::Join(elems, StringHelper::To("/")); + } + +public: + template + static bool IsSeparator(T s) + { + return s == static_cast('/') || s == static_cast('\\'); + } + + template + static std::basic_string Normalize(const std::basic_string& path) + { + if (path.size() == 0) + return path; + + auto paths = + StringHelper::Split(StringHelper::Replace(path, StringHelper::To("\\"), StringHelper::To("/")), static_cast('/')); + + return Normalize(paths); + } + + template + static std::basic_string Relative(const std::basic_string& targetPath, const std::basic_string& basePath) + { + if (basePath.size() == 0 || targetPath.size() == 0) + { + return targetPath; + } + + auto targetPaths = StringHelper::Split(StringHelper::Replace(targetPath, StringHelper::To("\\"), StringHelper::To("/")), + static_cast('/')); + auto basePaths = + StringHelper::Split(StringHelper::Replace(basePath, StringHelper::To("\\"), StringHelper::To("/")), static_cast('/')); + + if (*(basePath.end() - 1) != static_cast('/') && *(basePath.end() - 1) != static_cast('\\')) + { + basePaths.pop_back(); + } + + int32_t offset = 0; + while (targetPaths.size() > offset && basePaths.size() > offset) + { + if (targetPaths[offset] == basePaths[offset]) + { + offset++; + } + else + { + break; + } + } + + std::basic_string ret; + + for (size_t i = offset; i < basePaths.size(); i++) + { + ret += StringHelper::To("../"); + } + + for (size_t i = offset; i < targetPaths.size(); i++) + { + ret += targetPaths[i]; + + if (i != targetPaths.size() - 1) + { + ret += StringHelper::To("/"); + } + } + + return ret; + } + + template + static std::basic_string Absolute(const std::basic_string& targetPath, const std::basic_string& basePath) + { + if (targetPath == StringHelper::To("")) + return StringHelper::To(""); + + if (basePath == StringHelper::To("")) + return targetPath; + + auto targetPaths = StringHelper::Split(StringHelper::Replace(targetPath, StringHelper::To("\\"), StringHelper::To("/")), + static_cast('/')); + auto basePaths = + StringHelper::Split(StringHelper::Replace(basePath, StringHelper::To("\\"), StringHelper::To("/")), static_cast('/')); + + if (*(basePath.end() - 1) != static_cast('/') && *(basePath.end() - 1) != static_cast('\\')) + { + basePaths.pop_back(); + } + + std::copy(targetPaths.begin(), targetPaths.end(), std::back_inserter(basePaths)); + + return Normalize(basePaths); + } + + template + static std::basic_string GetDirectoryName(const std::basic_string& path) + { + if (path == StringHelper::To("")) + return StringHelper::To(""); + + int last_separator = -1; + for (size_t i = 0; i < path.size(); i++) + { + if (IsSeparator(path[i])) + { + last_separator = i; + } + } + + if (last_separator >= 0) + { + return path.substr(0, last_separator + 1); + } + return StringHelper::To(""); + } + + template + static std::basic_string GetFilenameWithoutExt(const std::basic_string& path) + { + if (path == StringHelper::To("")) + return StringHelper::To(""); + + int last_separator = -1; + for (size_t i = 0; i < path.size(); i++) + { + if (IsSeparator(path[i])) + { + last_separator = i; + } + } + last_separator++; + + int last_dot = -1; + for (size_t i = last_separator; i < path.size(); i++) + { + if (path[i] == static_cast('.')) + { + last_dot = i; + } + } + + if (last_dot >= 0) + { + return path.substr(last_separator, last_dot - last_separator); + } + return path.substr(last_separator, path.size() - last_separator); + } +}; + +} // namespace Effekseer + +#endif