Compare commits

...
5 Commits
Author SHA1 Message Date
Abseil Team 49495eacfd Use STL capabilities to choose GTEST_HAS_STD_WSTRING default
If the standard library claims not to support wide character strings, disable `GTEST_HAS_STD_WSTRING` and disallow users overriding it. If the standard library implementation can't be recognized, fall back to using the existing list of OSes with a known lack of support.

PiperOrigin-RevId: 964237076
Change-Id: I906f296259f8f17099990d51447a0d0d04dead66
2026-08-13 12:44:03 -07:00
Abseil Team aa1eefe02c Don't reference std::char_traits<wchar_t> when !GTEST_HAS_STD_WSTRING
If the standard library doesn't support wide character strings, `std::char_traits<Char>` won't be defined, so the definition of `PrintTo` shouldn't reference it. Use `wstrlen` directly instead.

PiperOrigin-RevId: 964168903
Change-Id: Ic628e6583679073b47bb1218dcf52b4c9eadaaf6
2026-08-13 10:39:39 -07:00
Abseil Team 002d14757f When Return is passed to WillOnce (i.e. converted to OnceAction) delegate to be equivalent to Return(ByMove(...))
This should eliminate most required usages of ByMove(...).

PiperOrigin-RevId: 964026018
Change-Id: I2dd5a56842ae3823b200c16b575960b6c367ca20
2026-08-13 05:34:04 -07:00
Abseil Team 02e50550c6 Default-enable wstring support for Android API level 21 and above.
Android started supporting std::wstring with API Level 21 (Lollipop). On Android, unless `GTEST_HAS_STD_WSTRING` is explicitly defined, set it based on the current Android API level.

PiperOrigin-RevId: 963538624
Change-Id: I1a19c4e5b0fef841e0650a1f95b45fa3439dee92
2026-08-12 10:47:59 -07:00
Prashant Kumar 963dd8ea18 Update version strings to 1.18
PiperOrigin-RevId: 962756240
Change-Id: Ibb440cda59a55a1dafc721f00140cbe0d726d077
2026-08-11 06:59:21 -07:00
7 changed files with 114 additions and 47 deletions
+3 -3
View File
@@ -8,12 +8,12 @@ Our documentation is now live on GitHub Pages at
https://google.github.io/googletest/. We recommend browsing the documentation on https://google.github.io/googletest/. We recommend browsing the documentation on
GitHub Pages rather than directly in the repository. GitHub Pages rather than directly in the repository.
#### Release 1.17.0 #### Release 1.18.0
[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is [Release 1.18.0](https://github.com/google/googletest/releases/tag/v1.18.0) is
now available. now available.
The 1.17.x branch The 1.18.x branch
[requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard). [requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
#### Continuous Integration #### Continuous Integration
+1 -1
View File
@@ -48,7 +48,7 @@ with the following content:
# Choose the most recent version available at # Choose the most recent version available at
# https://registry.bazel.build/modules/googletest # https://registry.bazel.build/modules/googletest
bazel_dep(name = "googletest", version = "1.17.0") bazel_dep(name = "googletest", version = "1.18.0")
``` ```
Now you're ready to build C++ code that uses GoogleTest. Now you're ready to build C++ code that uses GoogleTest.
+18 -20
View File
@@ -940,7 +940,7 @@ class [[nodiscard]] ReturnAction final {
std::is_convertible<R, U>, // std::is_convertible<R, U>, //
std::is_move_constructible<U>>::value>::type> std::is_move_constructible<U>>::value>::type>
operator OnceAction<U(Args...)>() && { // NOLINT operator OnceAction<U(Args...)>() && { // NOLINT
return Impl<U>(std::move(value_)); return OnceImpl<U>(std::move(value_));
} }
template <typename U, typename... Args, template <typename U, typename... Args,
@@ -959,13 +959,6 @@ class [[nodiscard]] ReturnAction final {
template <typename U> template <typename U>
class Impl final { class Impl final {
public: public:
// The constructor used when the return value is allowed to move from the
// input value (i.e. we are converting to OnceAction).
explicit Impl(R&& input_value)
: state_(new State(std::move(input_value))) {}
// The constructor used when the return value is not allowed to move from
// the input value (i.e. we are converting to Action).
explicit Impl(const R& input_value) : state_(new State(input_value)) {} explicit Impl(const R& input_value) : state_(new State(input_value)) {}
U operator()() && { return std::move(state_->value); } U operator()() && { return std::move(state_->value); }
@@ -996,18 +989,6 @@ class [[nodiscard]] ReturnAction final {
// explicit constructor from R. // explicit constructor from R.
value(ImplicitCast_<U>(internal::as_const(input_value))) {} value(ImplicitCast_<U>(internal::as_const(input_value))) {}
// As above, but for the case where we're moving from the ReturnAction
// object because it's being used as a OnceAction.
explicit State(R&& input_value_in)
: input_value(std::move(input_value_in)),
// For the same reason as above we make an implicit conversion to U
// before initializing the value.
//
// Unlike above we provide the input value as an rvalue to the
// implicit conversion because this is a OnceAction: it's fine if it
// wants to consume the input value.
value(ImplicitCast_<U>(std::move(input_value))) {}
// A copy of the value originally provided by the user. We retain this in // A copy of the value originally provided by the user. We retain this in
// addition to the value of the mock function's result type below in case // addition to the value of the mock function's result type below in case
// the latter is a reference-like type. See the std::string_view example // the latter is a reference-like type. See the std::string_view example
@@ -1085,6 +1066,23 @@ class [[nodiscard]] ReturnAction final {
const std::shared_ptr<State> state_; const std::shared_ptr<State> state_;
}; };
// Implements the Return(x) action for a mock function that returns type U,
// but is only executed at most once. This allows us to store the original
// value and move construct the return value type on the first (and only)
// call.
template <typename U>
class OnceImpl final {
public:
explicit OnceImpl(R&& input_value)
: input_value_(new R(std::move(input_value))) {}
U operator()() && { return std::move(*input_value_); }
private:
// Move the input value to the heap and make it copyable.
const std::shared_ptr<R> input_value_;
};
R value_; R value_;
}; };
+1 -1
View File
@@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
with with
``` ```
git clone https://github.com/google/googletest.git -b v1.17.0 git clone https://github.com/google/googletest.git -b v1.18.0
cd googletest # Main directory of the cloned repository. cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output. mkdir build # Create a directory to hold the build output.
cd build cd build
+4 -7
View File
@@ -1173,15 +1173,12 @@ class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
} }
} }
}; };
#endif
template <> template <>
class [[nodiscard]] UniversalTersePrinter<wchar_t*> { class [[nodiscard]] UniversalTersePrinter<wchar_t*>
public: : public UniversalTersePrinter<const wchar_t*> {};
static void Print(wchar_t* str, ::std::ostream* os) {
UniversalTersePrinter<const wchar_t*>::Print(str, os); #endif // GTEST_HAS_STD_WSTRING
}
};
template <typename T> template <typename T>
void UniversalTersePrint(const T& value, ::std::ostream* os) { void UniversalTersePrint(const T& value, ::std::ostream* os) {
+63 -14
View File
@@ -500,22 +500,71 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // defined(_MSC_VER) || defined(__BORLANDC__)
#endif // GTEST_HAS_EXCEPTIONS #endif // GTEST_HAS_EXCEPTIONS
#ifndef GTEST_HAS_STD_WSTRING // 1. Calculate default GTEST_HAS_STD_WSTRING values based on STL capabilities.
// The user didn't tell us whether ::std::wstring is available, so we need #if defined(_MSVC_STL_VERSION)
// to figure it out. // Microsoft's STL implementation always supports ::std::wstring.
// Cygwin 1.7 and below doesn't support ::std::wstring. #define GTEST_HAS_STD_WSTRING_DEFAULT 1
// Solaris' libc++ doesn't support it either. Android has
// no support for it at least as recent as Froyo (2.2). #elif defined(_LIBCPP_VERSION)
#if (!(defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_CYGWIN) || \ // Modern libc++ always defines _LIBCPP_HAS_WIDE_CHARACTERS; its value
defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_HAIKU) || \ // determines whether wide characters are supported.
defined(GTEST_OS_ESP32) || defined(GTEST_OS_ESP8266) || \ // Older libc++ omits a definition for _LIBCPP_HAS_NO_WIDE_CHARACTERS when wide
defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \ // characters are supported.
defined(GTEST_OS_NXP_QN9090) || defined(GTEST_OS_NRF52))) #if (defined(_LIBCPP_HAS_WIDE_CHARACTERS) && !_LIBCPP_HAS_WIDE_CHARACTERS) || \
#define GTEST_HAS_STD_WSTRING 1 defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
#define GTEST_HAS_STD_WSTRING_DEFAULT 0
#else #else
#define GTEST_HAS_STD_WSTRING 0 #define GTEST_HAS_STD_WSTRING_DEFAULT 1
#endif
#elif defined(__GLIBCXX__)
#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T
#define GTEST_HAS_STD_WSTRING_DEFAULT 1
#else
#define GTEST_HAS_STD_WSTRING_DEFAULT 0
#endif
#else
// Unknown standard library implementation; fall back looking at the OS.
//
// Always let the user override the defaults in this case; they might have more
// information about what's supported than we do.
#if defined(GTEST_OS_LINUX_ANDROID)
// Android started supporting std::wstring with API Level 21 (Lollipop).
#define GTEST_HAS_STD_WSTRING_DEFAULT (__ANDROID_API__ >= 21)
// The following platforms are known not to support ::std::wstring; assume it's
// supported on all others.
//
// Cygwin 1.7 and below doesn't support ::std::wstring.
// Solaris' libc++ doesn't support it either.
#elif defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_HAIKU) || defined(GTEST_OS_ESP32) || \
defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) || \
defined(GTEST_OS_NRF52)
#define GTEST_HAS_STD_WSTRING_DEFAULT 0
#else
#define GTEST_HAS_STD_WSTRING_DEFAULT 1
#endif
#endif
// 2. Validate explicit user overrides (if user passed -DGTEST_HAS_*=1) against
// what the standard library implementation tells us it supports.
#if defined(GTEST_HAS_STD_WSTRING) && GTEST_HAS_STD_WSTRING
#if defined(_LIBCPP_VERSION) && \
((defined(_LIBCPP_HAS_WIDE_CHARACTERS) && !_LIBCPP_HAS_WIDE_CHARACTERS) || \
defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS))
#error Cannot explicitly enable GTEST_HAS_STD_WSTRING without libc++ wide character support.
#elif defined(__GLIBCXX__) && \
!(defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T)
#error Cannot explicitly enable GTEST_HAS_STD_WSTRING without libstdc++ wide character support.
#endif
#endif
// 3. Set final values if not explicitly overridden by user
#if !defined(GTEST_HAS_STD_WSTRING)
#define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_WSTRING_DEFAULT
#endif #endif
#endif // GTEST_HAS_STD_WSTRING
#ifndef GTEST_HAS_FILE_SYSTEM #ifndef GTEST_HAS_FILE_SYSTEM
// Most platforms support a file system. // Most platforms support a file system.
+24 -1
View File
@@ -50,6 +50,7 @@
#include <iomanip> #include <iomanip>
#include <ios> #include <ios>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <string>
#include <string_view> #include <string_view>
#include <type_traits> #include <type_traits>
@@ -422,6 +423,28 @@ void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
namespace { namespace {
template <typename Char>
size_t GetLength(const Char* s) {
return std::char_traits<Char>::length(s);
}
#if !GTEST_HAS_STD_WSTRING
// If GTEST_HAS_STD_WSTRING is unset because the standard library has disabled
// wide character support, std::char_traits<wchar_t> won't be defined, which
// will cause a compile error, even if user code never actually could print a
// wide cstring. In that case, instead use `wcslen` directly.
//
// If `libc` _also_ lacks wide character support, this (and a bunch of other
// calls to wc functions) will fail to link, but only if user code actually
// uses them.
template <>
size_t GetLength<wchar_t>(const wchar_t* s) {
return wcslen(s);
}
#endif // GTEST_HAS_STD_WSTRING
// Prints a null-terminated C-style string to the ostream. // Prints a null-terminated C-style string to the ostream.
template <typename Char> template <typename Char>
void PrintCStringTo(const Char* s, ostream* os) { void PrintCStringTo(const Char* s, ostream* os) {
@@ -429,7 +452,7 @@ void PrintCStringTo(const Char* s, ostream* os) {
*os << "NULL"; *os << "NULL";
} else { } else {
*os << ImplicitCast_<const void*>(s) << " pointing to "; *os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os); PrintCharsAsStringTo(s, GetLength(s), os);
} }
} }