// ---------------------------------------------------------------------------- // - Open3D: www.open3d.org - // ---------------------------------------------------------------------------- // Copyright (c) 2018-2023 www.open3d.org // SPDX-License-Identifier: MIT // ---------------------------------------------------------------------------- #pragma once #include #include #include #include #include #include #include #include #include namespace open3d { namespace utility { /// hash_tuple defines a general hash function for std::tuple /// See this post for details: /// http://stackoverflow.com/questions/7110301 /// The hash_combine code is from boost /// Reciprocal of the golden ratio helps spread entropy and handles duplicates. /// See Mike Seymour in magic-numbers-in-boosthash-combine: /// http://stackoverflow.com/questions/4948780 template struct hash_tuple { size_t operator()(TT const& tt) const { return std::hash()(tt); } }; namespace { template inline void hash_combine(std::size_t& hash_seed, T const& v) { hash_seed ^= std::hash()(v) + 0x9e3779b9 + (hash_seed << 6) + (hash_seed >> 2); } template ::value - 1> struct HashValueImpl { static void apply(size_t& hash_seed, Tuple const& tuple) { HashValueImpl::apply(hash_seed, tuple); hash_combine(hash_seed, std::get(tuple)); } }; template struct HashValueImpl { static void apply(size_t& hash_seed, Tuple const& tuple) { hash_combine(hash_seed, std::get<0>(tuple)); } }; } // unnamed namespace template struct hash_tuple> { size_t operator()(std::tuple const& tt) const { size_t hash_seed = 0; HashValueImpl>::apply(hash_seed, tt); return hash_seed; } }; template struct hash_eigen { std::size_t operator()(T const& matrix) const { size_t hash_seed = 0; for (int i = 0; i < (int)matrix.size(); i++) { auto elem = *(matrix.data() + i); hash_seed ^= std::hash()(elem) + 0x9e3779b9 + (hash_seed << 6) + (hash_seed >> 2); } return hash_seed; } }; // Hash function for enum class for C++ standard less than C++14 // https://stackoverflow.com/a/24847480/1255535 struct hash_enum_class { template std::size_t operator()(T t) const { return static_cast(t); } }; /// Function to split a string, mimics boost::split /// http://stackoverflow.com/questions/236129/split-a-string-in-c std::vector SplitString(const std::string& str, const std::string& delimiters = " ", bool trim_empty_str = true); /// Returns true of the source string contains the destination string. /// \param src Source string. /// \param dst Destination string. bool ContainsString(const std::string& src, const std::string& dst); /// Returns true if \p src starts with \p tar. /// \param src Source string. /// \param tar Target string. bool StringStartsWith(const std::string& src, const std::string& tar); /// Returns true if \p src ends with \p tar. /// \param src Source string. /// \param tar Target string. bool StringEndsWith(const std::string& src, const std::string& tar); std::string JoinStrings(const std::vector& strs, const std::string& delimiter = ", "); /// String util: find length of current word staring from a position /// By default, alpha numeric chars and chars in valid_chars are considered /// as valid characters in a word size_t WordLength(const std::string& doc, size_t start_pos, const std::string& valid_chars = "_"); std::string& LeftStripString(std::string& str, const std::string& chars = "\t\n\v\f\r "); std::string& RightStripString(std::string& str, const std::string& chars = "\t\n\v\f\r "); /// Strip empty characters in front and after string. Similar to Python's /// str.strip() std::string& StripString(std::string& str, const std::string& chars = "\t\n\v\f\r "); /// Convert string to the lower case std::string ToLower(const std::string& s); /// Convert string to the upper case std::string ToUpper(const std::string& s); /// Format string template inline std::string FormatString(const std::string& format, Args... args) { int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' if (size_s <= 0) { throw std::runtime_error("Error during formatting."); } auto size = static_cast(size_s); auto buf = std::make_unique(size); std::snprintf(buf.get(), size, format.c_str(), args...); return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside }; /// Format string fast (Unix / BSD Only) template inline std::string FastFormatString(const std::string& format, Args... args) { #ifdef _WIN32 return FormatString(format, args...); #else char* buffer = nullptr; int size_s = asprintf(&buffer, format.c_str(), args...); if (size_s == -1) { throw std::runtime_error("Error during formatting."); } auto ret = std::string(buffer, buffer + size_s); // no + 1 since we ignore the \0 std::free(buffer); // asprintf calls malloc return ret; #endif // _WIN32 }; void Sleep(int milliseconds); /// Computes the quotient of x/y with rounding up inline int DivUp(int x, int y) { div_t tmp = std::div(x, y); return tmp.quot + (tmp.rem != 0 ? 1 : 0); } /// Returns current time stamp. std::string GetCurrentTimeStamp(); } // namespace utility } // namespace open3d