Add Chromium-only Blender WebEngine parity work
This commit is contained in:
189
blender-5.2.0/source/blender/blenlib/BLI_ustring.hh
Normal file
189
blender-5.2.0/source/blender/blenlib/BLI_ustring.hh
Normal file
@@ -0,0 +1,189 @@
|
||||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef WITH_WEB
|
||||
/* The Web data target does not compile OpenImageIO. Keep the UString API
|
||||
* available for DNA/node data while using a deterministic local representation. */
|
||||
#else
|
||||
#include <OpenImageIO/ustring.h>
|
||||
#endif
|
||||
|
||||
#include "BLI_fixed_string.hh"
|
||||
#include "BLI_hash.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/**
|
||||
* This is a thin wrapper around OpenImageIO's ustring class. Additionally it also provides
|
||||
* conversions to our StringRef types.
|
||||
*
|
||||
* See the OpenImageIO documentation for more details:
|
||||
* https://openimageio.readthedocs.io/en/stable/imageioapi.html#efficient-unique-strings-ustring
|
||||
*/
|
||||
class UString {
|
||||
private:
|
||||
/**
|
||||
* Using a member instead of inheritance because it simplifies avoiding various ambiguities with
|
||||
* operator overloads (especially equality comparison between UString, StringRef, std::string,
|
||||
* std::string_view, OpenImageIO::string_view, etc.).
|
||||
*/
|
||||
#ifdef WITH_WEB
|
||||
std::string ustr_;
|
||||
#else
|
||||
OIIO::ustring ustr_;
|
||||
#endif
|
||||
|
||||
public:
|
||||
UString() = default;
|
||||
#ifdef WITH_WEB
|
||||
explicit UString(const char *str) : ustr_(str ? str : "") {}
|
||||
explicit UString(const StringRef str) : ustr_(std::string_view(str)) {}
|
||||
#else
|
||||
explicit UString(const StringRef str) : ustr_(std::string_view(str)) {}
|
||||
#endif
|
||||
|
||||
/** A constructor that is meant to generate as little code as possible at the call site. */
|
||||
static UString from_ptr_noinline(const char *str);
|
||||
|
||||
/**
|
||||
* Access the underlying string as a #StringRefNull.
|
||||
*
|
||||
* Note: This is not an implicit conversion to work around ambiguous function calls.
|
||||
*/
|
||||
StringRefNull ref() const
|
||||
{
|
||||
#ifdef WITH_WEB
|
||||
return StringRefNull(ustr_.c_str(), ustr_.length());
|
||||
#else
|
||||
return StringRefNull(ustr_.c_str(), ustr_.length());
|
||||
#endif
|
||||
}
|
||||
|
||||
const std::string &string() const
|
||||
{
|
||||
#ifdef WITH_WEB
|
||||
return ustr_;
|
||||
#else
|
||||
return ustr_.string();
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *c_str() const
|
||||
{
|
||||
return ustr_.c_str();
|
||||
}
|
||||
|
||||
friend bool operator==(const UString &a, const UString &b)
|
||||
{
|
||||
return a.ustr_ == b.ustr_;
|
||||
}
|
||||
|
||||
friend bool operator==(const UString &a, const StringRef b)
|
||||
{
|
||||
return a.ref() == b;
|
||||
}
|
||||
|
||||
uint64_t hash() const
|
||||
{
|
||||
#ifdef WITH_WEB
|
||||
/* FNV-1a is stable across native/Web builds and does not require OIIO. */
|
||||
uint64_t result = UINT64_C(14695981039346656037);
|
||||
for (const unsigned char byte : ustr_) {
|
||||
result ^= byte;
|
||||
result *= UINT64_C(1099511628211);
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return ustr_.hash();
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t size() const
|
||||
{
|
||||
return int64_t(ustr_.size());
|
||||
}
|
||||
|
||||
bool is_empty() const
|
||||
{
|
||||
return ustr_.empty();
|
||||
}
|
||||
|
||||
char operator[](const int64_t i) const
|
||||
{
|
||||
/* Accessing null char at end is allowed too. */
|
||||
BLI_assert(i >= 0 && i <= this->size());
|
||||
return ustr_[i];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Define DefaultHash for UString keys so that it uses the cached hash on ustrings but also
|
||||
* supports hashing arbitrary (non-unique) strings in the same way.
|
||||
*
|
||||
* Note: The string hashes produced here are different from e.g. DefaultHash<StringRef>. That is
|
||||
* fine though. The only requirement is that all hashes defined in this template specialization are
|
||||
* compatible with each other.
|
||||
*/
|
||||
template<> struct DefaultHash<UString> {
|
||||
uint64_t operator()(const UString &value) const
|
||||
{
|
||||
return value.hash();
|
||||
}
|
||||
|
||||
constexpr uint64_t operator()(const StringRef value) const
|
||||
{
|
||||
#ifdef WITH_WEB
|
||||
uint64_t result = UINT64_C(14695981039346656037);
|
||||
for (const unsigned char byte : value) {
|
||||
result ^= byte;
|
||||
result *= UINT64_C(1099511628211);
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
/* This is the hash function used by OpenImageIO::ustring::make_unique internally. */
|
||||
return OIIO::Strutil::strhash64(value.size(), value.data());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a UString from a string literal. This is a template function so that each string is only
|
||||
* made unique once and not every time the literal is used.
|
||||
*
|
||||
* Note: OpenImageIO defines a similar `_us` string literal operator. However, it newly constructs
|
||||
* the ustring in each invocation instead of caching it in a static variable. Caching it like here
|
||||
* likely only works in C++20.
|
||||
*/
|
||||
template<FixedString FStr> inline UString operator""_ustr()
|
||||
{
|
||||
static const UString static_ustr = UString::from_ptr_noinline(FStr.data);
|
||||
return static_ustr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support using the `fmt` library with #UString.
|
||||
*/
|
||||
inline std::string_view format_as(UString str)
|
||||
{
|
||||
return str.string();
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
|
||||
/**
|
||||
* Disable conflicting range formatter in fmtlib. Otherwise we will get compile errors
|
||||
* where fmtlib doesn't know if it should use the formatter from format.h or ranges.h.
|
||||
*/
|
||||
namespace fmt {
|
||||
|
||||
template<> struct is_range<blender::UString, char> : std::false_type {};
|
||||
|
||||
} // namespace fmt
|
||||
Reference in New Issue
Block a user