@ -0,0 +1,113 @@
|
||||
// Copyright 2017 The Effcee Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef EFFCEE_EFFCEE_H
|
||||
#define EFFCEE_EFFCEE_H
|
||||
|
||||
#include <string>
|
||||
#include "re2/re2.h"
|
||||
|
||||
namespace effcee {
|
||||
|
||||
// TODO(dneto): Provide a check language tutorial / manual.
|
||||
|
||||
// This does not implement the equivalents of FileCheck options:
|
||||
// --match-full-lines
|
||||
// --strict-whitespace
|
||||
// --implicit-ch3eck-not
|
||||
// --enable-var-scope
|
||||
|
||||
using StringPiece = re2::StringPiece;
|
||||
|
||||
// Options for matching.
|
||||
class Options {
|
||||
public:
|
||||
Options()
|
||||
: prefix_("CHECK"), input_name_("<stdin>"), checks_name_("<stdin>") {}
|
||||
|
||||
// Sets rule prefix to a copy of |prefix|. Returns this object.
|
||||
Options& SetPrefix(StringPiece prefix) {
|
||||
prefix_ = std::string(prefix.begin(), prefix.end());
|
||||
return *this;
|
||||
}
|
||||
const std::string& prefix() const { return prefix_; }
|
||||
|
||||
// Sets the input name. Returns this object.
|
||||
// Use this for file names, for example.
|
||||
Options& SetInputName(StringPiece name) {
|
||||
input_name_ = std::string(name.begin(), name.end());
|
||||
return *this;
|
||||
}
|
||||
const std::string& input_name() const { return input_name_; }
|
||||
|
||||
// Sets the checks input name. Returns this object.
|
||||
// Use this for file names, for example.
|
||||
Options& SetChecksName(StringPiece name) {
|
||||
checks_name_ = std::string(name.begin(), name.end());
|
||||
return *this;
|
||||
}
|
||||
const std::string& checks_name() const { return checks_name_; }
|
||||
|
||||
private:
|
||||
std::string prefix_;
|
||||
std::string input_name_;
|
||||
std::string checks_name_;
|
||||
};
|
||||
|
||||
// The result of an attempted match.
|
||||
class Result {
|
||||
public:
|
||||
enum class Status {
|
||||
Ok = 0,
|
||||
Fail, // A failure to match
|
||||
BadOption, // A bad option was specified
|
||||
NoRules, // No rules were specified
|
||||
BadRule, // A bad rule was specified
|
||||
};
|
||||
|
||||
// Constructs a result with a given status.
|
||||
explicit Result(Status status) : status_(status) {}
|
||||
// Constructs a result with the given message. Keeps a copy of the message.
|
||||
Result(Status status, StringPiece message)
|
||||
: status_(status), message_({message.begin(), message.end()}) {}
|
||||
|
||||
Status status() const { return status_; }
|
||||
|
||||
// Returns true if the match was successful.
|
||||
operator bool() const { return status_ == Status::Ok; }
|
||||
|
||||
const std::string& message() const { return message_; }
|
||||
|
||||
// Sets the error message to a copy of |message|. Returns this object.
|
||||
Result& SetMessage(StringPiece message) {
|
||||
message_ = std::string(message.begin(), message.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// Status code indicating success, or kind of failure.
|
||||
Status status_;
|
||||
|
||||
// Message describing the failure, if any. On success, this is empty.
|
||||
std::string message_;
|
||||
};
|
||||
|
||||
// Returns the result of attempting to match |text| against the pattern
|
||||
// program in |checks|, with the given |options|.
|
||||
Result Match(StringPiece text, StringPiece checks,
|
||||
const Options& options = Options());
|
||||
|
||||
} // namespace effcee
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,159 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used cardinalities. More
|
||||
// cardinalities can be defined by the user implementing the
|
||||
// CardinalityInterface interface if necessary.
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <memory>
|
||||
#include <ostream> // NOLINT
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement a cardinality Foo, define:
|
||||
// 1. a class FooCardinality that implements the
|
||||
// CardinalityInterface interface, and
|
||||
// 2. a factory function that creates a Cardinality object from a
|
||||
// const FooCardinality*.
|
||||
//
|
||||
// The two-level delegation design follows that of Matcher, providing
|
||||
// consistency for extension developers. It also eases ownership
|
||||
// management as Cardinality objects can now be copied like plain values.
|
||||
|
||||
// The implementation of a cardinality.
|
||||
class CardinalityInterface {
|
||||
public:
|
||||
virtual ~CardinalityInterface() = default;
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
virtual int ConservativeLowerBound() const { return 0; }
|
||||
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
||||
|
||||
// Returns true if and only if call_count calls will satisfy this
|
||||
// cardinality.
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Returns true if and only if call_count calls will saturate this
|
||||
// cardinality.
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
||||
|
||||
// Describes self to an ostream.
|
||||
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||
};
|
||||
|
||||
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that specifies how many times a mock function is expected to
|
||||
// be called. The implementation of Cardinality is just a std::shared_ptr
|
||||
// to const CardinalityInterface. Don't inherit from Cardinality!
|
||||
class GTEST_API_ Cardinality {
|
||||
public:
|
||||
// Constructs a null cardinality. Needed for storing Cardinality
|
||||
// objects in STL containers.
|
||||
Cardinality() = default;
|
||||
|
||||
// Constructs a Cardinality from its implementation.
|
||||
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||
|
||||
// Conservative estimate on the lower/upper bound of the number of
|
||||
// calls allowed.
|
||||
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
||||
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
||||
|
||||
// Returns true if and only if call_count calls will satisfy this
|
||||
// cardinality.
|
||||
bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true if and only if call_count calls will saturate this
|
||||
// cardinality.
|
||||
bool IsSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Returns true if and only if call_count calls will over-saturate this
|
||||
// cardinality, i.e. exceed the maximum number of allowed calls.
|
||||
bool IsOverSaturatedByCallCount(int call_count) const {
|
||||
return impl_->IsSaturatedByCallCount(call_count) &&
|
||||
!impl_->IsSatisfiedByCallCount(call_count);
|
||||
}
|
||||
|
||||
// Describes self to an ostream
|
||||
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||
|
||||
// Describes the given actual call count to an ostream.
|
||||
static void DescribeActualCallCountTo(int actual_call_count,
|
||||
::std::ostream* os);
|
||||
|
||||
private:
|
||||
std::shared_ptr<const CardinalityInterface> impl_;
|
||||
};
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
GTEST_API_ Cardinality AtLeast(int n);
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
GTEST_API_ Cardinality AtMost(int n);
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
GTEST_API_ Cardinality AnyNumber();
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
GTEST_API_ Cardinality Between(int min, int max);
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
GTEST_API_ Cardinality Exactly(int n);
|
||||
|
||||
// Creates a cardinality from its implementation.
|
||||
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
|
||||
return Cardinality(c);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||
@ -0,0 +1,519 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements MOCK_METHOD.
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits> // IWYU pragma: keep
|
||||
#include <utility> // IWYU pragma: keep
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-pp.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
using identity_t = T;
|
||||
|
||||
template <typename Pattern>
|
||||
struct ThisRefAdjuster {
|
||||
template <typename T>
|
||||
using AdjustT = typename std::conditional<
|
||||
std::is_const<typename std::remove_reference<Pattern>::type>::value,
|
||||
typename std::conditional<std::is_lvalue_reference<Pattern>::value,
|
||||
const T&, const T&&>::type,
|
||||
typename std::conditional<std::is_lvalue_reference<Pattern>::value, T&,
|
||||
T&&>::type>::type;
|
||||
|
||||
template <typename MockType>
|
||||
static AdjustT<MockType> Adjust(const MockType& mock) {
|
||||
return static_cast<AdjustT<MockType>>(const_cast<MockType&>(mock));
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool PrefixOf(const char* a, const char* b) {
|
||||
return *a == 0 || (*a == *b && internal::PrefixOf(a + 1, b + 1));
|
||||
}
|
||||
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool StartsWith(const char (&prefix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(prefix, str);
|
||||
}
|
||||
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool EndsWith(const char (&suffix)[N], const char (&str)[M]) {
|
||||
return N <= M && internal::PrefixOf(suffix, str + M - N);
|
||||
}
|
||||
|
||||
template <size_t N, size_t M>
|
||||
constexpr bool Equals(const char (&a)[N], const char (&b)[M]) {
|
||||
return N == M && internal::PrefixOf(a, b);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
constexpr bool ValidateSpec(const char (&spec)[N]) {
|
||||
return internal::Equals("const", spec) ||
|
||||
internal::Equals("override", spec) ||
|
||||
internal::Equals("final", spec) ||
|
||||
internal::Equals("noexcept", spec) ||
|
||||
(internal::StartsWith("noexcept(", spec) &&
|
||||
internal::EndsWith(")", spec)) ||
|
||||
internal::Equals("ref(&)", spec) ||
|
||||
internal::Equals("ref(&&)", spec) ||
|
||||
(internal::StartsWith("Calltype(", spec) &&
|
||||
internal::EndsWith(")", spec));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the FunctionMocker class template
|
||||
// is meant to be defined in the ::testing namespace. The following
|
||||
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||
// cannot handle it if we define FunctionMocker in ::testing.
|
||||
using internal::FunctionMocker;
|
||||
} // namespace testing
|
||||
|
||||
#define MOCK_METHOD(...) \
|
||||
GMOCK_INTERNAL_WARNING_PUSH() \
|
||||
GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \
|
||||
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) \
|
||||
GMOCK_INTERNAL_WARNING_POP()
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
|
||||
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
|
||||
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
|
||||
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \
|
||||
GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Spec), \
|
||||
GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \
|
||||
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \
|
||||
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_WRONG_ARITY(...) \
|
||||
static_assert( \
|
||||
false, \
|
||||
"MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \
|
||||
"_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \
|
||||
"enclosed in parentheses. If _Ret is a type with unprotected commas, " \
|
||||
"it must also be enclosed in parentheses.")
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \
|
||||
static_assert( \
|
||||
GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \
|
||||
GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.")
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \
|
||||
static_assert( \
|
||||
std::is_function<__VA_ARGS__>::value, \
|
||||
"Signature must be a function type, maybe return type contains " \
|
||||
"unprotected comma."); \
|
||||
static_assert( \
|
||||
::testing::tuple_size<typename ::testing::internal::Function< \
|
||||
__VA_ARGS__>::ArgumentTuple>::value == _N, \
|
||||
"This method does not take " GMOCK_PP_STRINGIZE( \
|
||||
_N) " arguments. Parenthesize all types with unprotected commas.")
|
||||
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
|
||||
_Override, _Final, _NoexceptSpec, \
|
||||
_CallType, _RefSpec, _Signature) \
|
||||
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
|
||||
_Signature)>::Result \
|
||||
GMOCK_INTERNAL_EXPAND(_CallType) \
|
||||
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
|
||||
GMOCK_PP_IF(_Constness, const, ) \
|
||||
_RefSpec _NoexceptSpec GMOCK_PP_IF(_Override, override, ) \
|
||||
GMOCK_PP_IF(_Final, final, ) { \
|
||||
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
.SetOwnerAndName(this, #_MethodName); \
|
||||
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
.Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
|
||||
} \
|
||||
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
|
||||
GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \
|
||||
GMOCK_PP_IF(_Constness, const, ) _RefSpec { \
|
||||
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
|
||||
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
|
||||
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
|
||||
} \
|
||||
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
|
||||
const ::testing::internal::WithoutMatchers&, \
|
||||
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
|
||||
GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \
|
||||
return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF( \
|
||||
_Constness, const, ) int _RefSpec>::Adjust(*this) \
|
||||
.gmock_##_MethodName(GMOCK_PP_REPEAT( \
|
||||
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
|
||||
} \
|
||||
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
|
||||
GMOCK_MOCKER_(_N, _Constness, _MethodName)
|
||||
|
||||
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
|
||||
|
||||
// Valid modifiers.
|
||||
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
|
||||
|
||||
#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \
|
||||
GMOCK_PP_HAS_COMMA( \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))
|
||||
|
||||
#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
|
||||
|
||||
#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple)
|
||||
|
||||
#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem) \
|
||||
GMOCK_PP_IF( \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \
|
||||
_elem, )
|
||||
|
||||
#define GMOCK_INTERNAL_GET_CALLTYPE_SPEC(_Tuple) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE, ~, _Tuple)
|
||||
|
||||
#define GMOCK_INTERNAL_CALLTYPE_SPEC_IF_CALLTYPE(_i, _, _elem) \
|
||||
GMOCK_PP_IF( \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem)), \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
|
||||
|
||||
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple)
|
||||
|
||||
#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem) \
|
||||
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), )
|
||||
|
||||
#ifdef GMOCK_INTERNAL_STRICT_SPEC_ASSERT
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||
static_assert( \
|
||||
::testing::internal::ValidateSpec(GMOCK_PP_STRINGIZE(_elem)), \
|
||||
"Token \'" GMOCK_PP_STRINGIZE( \
|
||||
_elem) "\' cannot be recognized as a valid specification " \
|
||||
"modifier. Is a ',' missing?");
|
||||
#else
|
||||
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
|
||||
static_assert( \
|
||||
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem))) == 1, \
|
||||
GMOCK_PP_STRINGIZE( \
|
||||
_elem) " cannot be recognized as a valid specification modifier.");
|
||||
#endif // GMOCK_INTERNAL_STRICT_SPEC_ASSERT
|
||||
|
||||
// Modifiers implementation.
|
||||
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_CONST_I_const ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_REF_I_ref ,
|
||||
|
||||
#define GMOCK_INTERNAL_UNPACK_ref(x) x
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_CALLTYPE(_i, _, _elem) \
|
||||
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CALLTYPE_I_, _elem)
|
||||
|
||||
#define GMOCK_INTERNAL_DETECT_CALLTYPE_I_Calltype ,
|
||||
|
||||
#define GMOCK_INTERNAL_UNPACK_Calltype(...) __VA_ARGS__
|
||||
|
||||
// Note: The use of `identity_t` here allows _Ret to represent return types that
|
||||
// would normally need to be specified in a different way. For example, a method
|
||||
// returning a function pointer must be written as
|
||||
//
|
||||
// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...)
|
||||
//
|
||||
// But we only support placing the return type at the beginning. To handle this,
|
||||
// we wrap all calls in identity_t, so that a declaration will be expanded to
|
||||
//
|
||||
// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...)
|
||||
//
|
||||
// This allows us to work around the syntactic oddities of function/method
|
||||
// types.
|
||||
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
|
||||
::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \
|
||||
GMOCK_PP_REMOVE_PARENS, \
|
||||
GMOCK_PP_IDENTITY)(_Ret)>( \
|
||||
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
|
||||
|
||||
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \
|
||||
GMOCK_PP_IDENTITY) \
|
||||
(_elem)
|
||||
|
||||
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
|
||||
gmock_a##_i
|
||||
|
||||
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
::std::forward<GMOCK_INTERNAL_ARG_O( \
|
||||
_i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i)
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \
|
||||
gmock_a##_i
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
gmock_a##_i
|
||||
|
||||
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
|
||||
GMOCK_PP_COMMA_IF(_i) \
|
||||
::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>()
|
||||
|
||||
#define GMOCK_INTERNAL_ARG_O(_i, ...) \
|
||||
typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type
|
||||
|
||||
#define GMOCK_INTERNAL_MATCHER_O(_i, ...) \
|
||||
const ::testing::Matcher<typename ::testing::internal::Function< \
|
||||
__VA_ARGS__>::template Arg<_i>::type>&
|
||||
|
||||
#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__)
|
||||
#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__)
|
||||
#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__)
|
||||
#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__)
|
||||
#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__)
|
||||
#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__)
|
||||
#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__)
|
||||
#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__)
|
||||
#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__)
|
||||
#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__)
|
||||
#define MOCK_METHOD10(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10(m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__)
|
||||
|
||||
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
|
||||
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__)
|
||||
|
||||
#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \
|
||||
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
|
||||
args_num, ::testing::internal::identity_t<__VA_ARGS__>); \
|
||||
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
|
||||
args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, , \
|
||||
(::testing::internal::identity_t<__VA_ARGS__>))
|
||||
|
||||
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_FUNCTION_MOCKER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,658 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some commonly used variadic actions.
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock-actions.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
// Include any custom callback actions added by the local installation.
|
||||
#include "gmock/internal/custom/gmock-generated-actions.h"
|
||||
|
||||
// Sometimes you want to give an action explicit template parameters
|
||||
// that cannot be inferred from its value parameters. ACTION() and
|
||||
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
|
||||
// and can be viewed as an extension to ACTION() and ACTION_P*().
|
||||
//
|
||||
// The syntax:
|
||||
//
|
||||
// ACTION_TEMPLATE(ActionName,
|
||||
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
|
||||
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
|
||||
//
|
||||
// defines an action template that takes m explicit template
|
||||
// parameters and n value parameters. name_i is the name of the i-th
|
||||
// template parameter, and kind_i specifies whether it's a typename,
|
||||
// an integral constant, or a template. p_i is the name of the i-th
|
||||
// value parameter.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
|
||||
// // function to type T and copies it to *output.
|
||||
// ACTION_TEMPLATE(DuplicateArg,
|
||||
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||
// AND_1_VALUE_PARAMS(output)) {
|
||||
// *output = T(::std::get<k>(args));
|
||||
// }
|
||||
// ...
|
||||
// int n;
|
||||
// EXPECT_CALL(mock, Foo(_, _))
|
||||
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
|
||||
//
|
||||
// To create an instance of an action template, write:
|
||||
//
|
||||
// ActionName<t1, ..., t_m>(v1, ..., v_n)
|
||||
//
|
||||
// where the ts are the template arguments and the vs are the value
|
||||
// arguments. The value argument types are inferred by the compiler.
|
||||
// If you want to explicitly specify the value argument types, you can
|
||||
// provide additional template arguments:
|
||||
//
|
||||
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
|
||||
//
|
||||
// where u_i is the desired type of v_i.
|
||||
//
|
||||
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
|
||||
// number of value parameters, but not on the number of template
|
||||
// parameters. Without the restriction, the meaning of the following
|
||||
// is unclear:
|
||||
//
|
||||
// OverloadedAction<int, bool>(x);
|
||||
//
|
||||
// Are we using a single-template-parameter action where 'bool' refers
|
||||
// to the type of x, or are we using a two-template-parameter action
|
||||
// where the compiler is asked to infer the type of x?
|
||||
//
|
||||
// Implementation notes:
|
||||
//
|
||||
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
|
||||
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
|
||||
// implementing ACTION_TEMPLATE. The main trick we use is to create
|
||||
// new macro invocations when expanding a macro. For example, we have
|
||||
//
|
||||
// #define ACTION_TEMPLATE(name, template_params, value_params)
|
||||
// ... GMOCK_INTERNAL_DECL_##template_params ...
|
||||
//
|
||||
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
|
||||
// to expand to
|
||||
//
|
||||
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
|
||||
//
|
||||
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
|
||||
// preprocessor will continue to expand it to
|
||||
//
|
||||
// ... typename T ...
|
||||
//
|
||||
// This technique conforms to the C++ standard and is portable. It
|
||||
// allows us to implement action templates using O(N) code, where N is
|
||||
// the maximum number of template/value parameters supported. Without
|
||||
// using it, we'd have to devote O(N^2) amount of code to implement all
|
||||
// combinations of m and n.
|
||||
|
||||
// Declares the template parameters.
|
||||
#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0
|
||||
#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \
|
||||
kind0 name0, kind1 name1
|
||||
#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2) \
|
||||
kind0 name0, kind1 name1, kind2 name2
|
||||
#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3) \
|
||||
kind0 name0, kind1 name1, kind2 name2, kind3 name3
|
||||
#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \
|
||||
kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4
|
||||
#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, \
|
||||
kind4, name4, kind5, name5) \
|
||||
kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5
|
||||
#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6) \
|
||||
kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
|
||||
kind5 name5, kind6 name6
|
||||
#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6, kind7, name7) \
|
||||
kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
|
||||
kind5 name5, kind6 name6, kind7 name7
|
||||
#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6, kind7, name7, kind8, name8) \
|
||||
kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
|
||||
kind5 name5, kind6 name6, kind7 name7, kind8 name8
|
||||
#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \
|
||||
kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \
|
||||
kind5 name5, kind6 name6, kind7 name7, kind8 name8, kind9 name9
|
||||
|
||||
// Lists the template parameters.
|
||||
#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0
|
||||
#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, name1) \
|
||||
name0, name1
|
||||
#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2) \
|
||||
name0, name1, name2
|
||||
#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3) \
|
||||
name0, name1, name2, name3
|
||||
#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4) \
|
||||
name0, name1, name2, name3, name4
|
||||
#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \
|
||||
kind2, name2, kind3, name3, \
|
||||
kind4, name4, kind5, name5) \
|
||||
name0, name1, name2, name3, name4, name5
|
||||
#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6) \
|
||||
name0, name1, name2, name3, name4, name5, name6
|
||||
#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6, kind7, name7) \
|
||||
name0, name1, name2, name3, name4, name5, name6, name7
|
||||
#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6, kind7, name7, kind8, name8) \
|
||||
name0, name1, name2, name3, name4, name5, name6, name7, name8
|
||||
#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS( \
|
||||
kind0, name0, kind1, name1, kind2, name2, kind3, name3, kind4, name4, \
|
||||
kind5, name5, kind6, name6, kind7, name7, kind8, name8, kind9, name9) \
|
||||
name0, name1, name2, name3, name4, name5, name6, name7, name8, name9
|
||||
|
||||
// Declares the types of value parameters.
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) \
|
||||
, typename p0##_type, typename p1##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type, typename p7##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type, typename p7##_type, typename p8##_type
|
||||
#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8, p9) \
|
||||
, typename p0##_type, typename p1##_type, typename p2##_type, \
|
||||
typename p3##_type, typename p4##_type, typename p5##_type, \
|
||||
typename p6##_type, typename p7##_type, typename p8##_type, \
|
||||
typename p9##_type
|
||||
|
||||
// Initializes the value parameters.
|
||||
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS() ()
|
||||
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0) \
|
||||
(p0##_type gmock_p0) : p0(::std::move(gmock_p0))
|
||||
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1) \
|
||||
: p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1))
|
||||
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2))
|
||||
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3))
|
||||
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), \
|
||||
p4(::std::move(gmock_p4))
|
||||
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), \
|
||||
p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5))
|
||||
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), \
|
||||
p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), \
|
||||
p6(::std::move(gmock_p6))
|
||||
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6, p7##_type gmock_p7) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), \
|
||||
p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), \
|
||||
p6(::std::move(gmock_p6)), \
|
||||
p7(::std::move(gmock_p7))
|
||||
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \
|
||||
p8) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), \
|
||||
p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), \
|
||||
p6(::std::move(gmock_p6)), \
|
||||
p7(::std::move(gmock_p7)), \
|
||||
p8(::std::move(gmock_p8))
|
||||
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) \
|
||||
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
|
||||
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
|
||||
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
|
||||
p9##_type gmock_p9) \
|
||||
: p0(::std::move(gmock_p0)), \
|
||||
p1(::std::move(gmock_p1)), \
|
||||
p2(::std::move(gmock_p2)), \
|
||||
p3(::std::move(gmock_p3)), \
|
||||
p4(::std::move(gmock_p4)), \
|
||||
p5(::std::move(gmock_p5)), \
|
||||
p6(::std::move(gmock_p6)), \
|
||||
p7(::std::move(gmock_p7)), \
|
||||
p8(::std::move(gmock_p8)), \
|
||||
p9(::std::move(gmock_p9))
|
||||
|
||||
// Defines the copy constructor
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \
|
||||
{} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_4_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_5_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_6_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_7_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_8_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_9_VALUE_PARAMS(...) = default;
|
||||
#define GMOCK_INTERNAL_DEFN_COPY_AND_10_VALUE_PARAMS(...) = default;
|
||||
|
||||
// Declares the fields for storing the value parameters.
|
||||
#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2; \
|
||||
p3##_type p3;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2; \
|
||||
p3##_type p3; \
|
||||
p4##_type p4;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2; \
|
||||
p3##_type p3; \
|
||||
p4##_type p4; \
|
||||
p5##_type p5;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2; \
|
||||
p3##_type p3; \
|
||||
p4##_type p4; \
|
||||
p5##_type p5; \
|
||||
p6##_type p6;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2; \
|
||||
p3##_type p3; \
|
||||
p4##_type p4; \
|
||||
p5##_type p5; \
|
||||
p6##_type p6; \
|
||||
p7##_type p7;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \
|
||||
p8) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2; \
|
||||
p3##_type p3; \
|
||||
p4##_type p4; \
|
||||
p5##_type p5; \
|
||||
p6##_type p6; \
|
||||
p7##_type p7; \
|
||||
p8##_type p8;
|
||||
#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) \
|
||||
p0##_type p0; \
|
||||
p1##_type p1; \
|
||||
p2##_type p2; \
|
||||
p3##_type p3; \
|
||||
p4##_type p4; \
|
||||
p5##_type p5; \
|
||||
p6##_type p6; \
|
||||
p7##_type p7; \
|
||||
p8##_type p8; \
|
||||
p9##_type p9;
|
||||
|
||||
// Lists the value parameters.
|
||||
#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0
|
||||
#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1
|
||||
#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2
|
||||
#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3
|
||||
#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
|
||||
p0, p1, p2, p3, p4
|
||||
#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \
|
||||
p0, p1, p2, p3, p4, p5
|
||||
#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \
|
||||
p0, p1, p2, p3, p4, p5, p6
|
||||
#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \
|
||||
p0, p1, p2, p3, p4, p5, p6, p7
|
||||
#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \
|
||||
p8) \
|
||||
p0, p1, p2, p3, p4, p5, p6, p7, p8
|
||||
#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) \
|
||||
p0, p1, p2, p3, p4, p5, p6, p7, p8, p9
|
||||
|
||||
// Lists the value parameter types.
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) \
|
||||
, p0##_type, p1##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) \
|
||||
, p0##_type, p1##_type, p2##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \
|
||||
, p0##_type, p1##_type, p2##_type, p3##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
|
||||
, p0##_type, p1##_type, p2##_type, p3##_type, p4##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \
|
||||
, p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6) \
|
||||
, p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, p6##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7) \
|
||||
, p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \
|
||||
p6##_type, p7##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8) \
|
||||
, p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \
|
||||
p6##_type, p7##_type, p8##_type
|
||||
#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \
|
||||
p6, p7, p8, p9) \
|
||||
, p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \
|
||||
p6##_type, p7##_type, p8##_type, p9##_type
|
||||
|
||||
// Declares the value parameters.
|
||||
#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0
|
||||
#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) \
|
||||
p0##_type p0, p1##_type p1
|
||||
#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2
|
||||
#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3
|
||||
#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4
|
||||
#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5
|
||||
#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5, p6##_type p6
|
||||
#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5, p6##_type p6, p7##_type p7
|
||||
#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, \
|
||||
p8) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8
|
||||
#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) \
|
||||
p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \
|
||||
p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, p9##_type p9
|
||||
|
||||
// The suffix of the class template implementing the action template.
|
||||
#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS()
|
||||
#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P
|
||||
#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2
|
||||
#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3
|
||||
#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4
|
||||
#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5
|
||||
#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6
|
||||
#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7
|
||||
#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7) \
|
||||
P8
|
||||
#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8) \
|
||||
P9
|
||||
#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
|
||||
p7, p8, p9) \
|
||||
P10
|
||||
|
||||
// The name of the class template implementing the action template.
|
||||
#define GMOCK_ACTION_CLASS_(name, value_params) \
|
||||
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
||||
|
||||
#define ACTION_TEMPLATE(name, template_params, value_params) \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
class GMOCK_ACTION_CLASS_(name, value_params) { \
|
||||
public: \
|
||||
explicit GMOCK_ACTION_CLASS_(name, value_params)( \
|
||||
GMOCK_INTERNAL_DECL_##value_params) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||
= default; \
|
||||
, \
|
||||
: impl_(std::make_shared<gmock_Impl>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params)){}) \
|
||||
GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \
|
||||
name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||
##value_params \
|
||||
GMOCK_ACTION_CLASS_(name, value_params)(GMOCK_ACTION_CLASS_( \
|
||||
name, value_params) &&) noexcept GMOCK_INTERNAL_DEFN_COPY_ \
|
||||
##value_params template <typename F> \
|
||||
operator ::testing::Action<F>() const { \
|
||||
return GMOCK_PP_IF( \
|
||||
GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \
|
||||
(::testing::internal::MakeAction<F, gmock_Impl>()), \
|
||||
(::testing::internal::MakeAction<F>(impl_))); \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
class gmock_Impl { \
|
||||
public: \
|
||||
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \
|
||||
template <typename function_type, typename return_type, \
|
||||
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
|
||||
GMOCK_INTERNAL_DEFN_##value_params \
|
||||
}; \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), , \
|
||||
std::shared_ptr<const gmock_Impl> impl_;) \
|
||||
}; \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
GMOCK_ACTION_CLASS_( \
|
||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
inline GMOCK_ACTION_CLASS_( \
|
||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params> \
|
||||
name(GMOCK_INTERNAL_DECL_##value_params) { \
|
||||
return GMOCK_ACTION_CLASS_( \
|
||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>( \
|
||||
GMOCK_INTERNAL_LIST_##value_params); \
|
||||
} \
|
||||
template <GMOCK_INTERNAL_DECL_##template_params \
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params> \
|
||||
template <typename function_type, typename return_type, typename args_type, \
|
||||
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
|
||||
return_type GMOCK_ACTION_CLASS_( \
|
||||
name, value_params)<GMOCK_INTERNAL_LIST_##template_params \
|
||||
GMOCK_INTERNAL_LIST_TYPE_##value_params>:: \
|
||||
gmock_Impl::gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) \
|
||||
const
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||
// the macro definition, as the warnings are generated when the macro
|
||||
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||
// we suppress them here.
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
|
||||
namespace internal {
|
||||
|
||||
// internal::InvokeArgument - a helper for InvokeArgument action.
|
||||
// The basic overloads are provided here for generic functors.
|
||||
// Overloads for other custom-callables are provided in the
|
||||
// internal/custom/gmock-generated-actions.h header.
|
||||
template <typename F, typename... Args>
|
||||
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) {
|
||||
return f(args...);
|
||||
}
|
||||
|
||||
template <std::size_t index, typename... Params>
|
||||
struct InvokeArgumentAction {
|
||||
template <typename... Args,
|
||||
typename = typename std::enable_if<(index < sizeof...(Args))>::type>
|
||||
auto operator()(Args &&...args) const -> decltype(internal::InvokeArgument(
|
||||
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)),
|
||||
std::declval<const Params &>()...)) {
|
||||
internal::FlatTuple<Args &&...> args_tuple(FlatTupleConstructTag{},
|
||||
std::forward<Args>(args)...);
|
||||
return params.Apply([&](const Params &...unpacked_params) {
|
||||
auto &&callable = args_tuple.template Get<index>();
|
||||
return internal::InvokeArgument(
|
||||
std::forward<decltype(callable)>(callable), unpacked_params...);
|
||||
});
|
||||
}
|
||||
|
||||
internal::FlatTuple<Params...> params;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
|
||||
// (0-based) argument, which must be a k-ary callable, of the mock
|
||||
// function, with arguments a1, a2, ..., a_k.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// 1. The arguments are passed by value by default. If you need to
|
||||
// pass an argument by reference, wrap it inside std::ref(). For
|
||||
// example,
|
||||
//
|
||||
// InvokeArgument<1>(5, string("Hello"), std::ref(foo))
|
||||
//
|
||||
// passes 5 and string("Hello") by value, and passes foo by
|
||||
// reference.
|
||||
//
|
||||
// 2. If the callable takes an argument by reference but std::ref() is
|
||||
// not used, it will receive the reference to a copy of the value,
|
||||
// instead of the original value. For example, when the 0-th
|
||||
// argument of the mock function takes a const string&, the action
|
||||
//
|
||||
// InvokeArgument<0>(string("Hello"))
|
||||
//
|
||||
// makes a copy of the temporary string("Hello") object and passes a
|
||||
// reference of the copy, instead of the original temporary object,
|
||||
// to the callable. This makes it easy for a user to define an
|
||||
// InvokeArgument action from temporary values and have it performed
|
||||
// later.
|
||||
template <std::size_t index, typename... Params>
|
||||
internal::InvokeArgumentAction<index, typename std::decay<Params>::type...>
|
||||
InvokeArgument(Params &&...params) {
|
||||
return {internal::FlatTuple<typename std::decay<Params>::type...>(
|
||||
internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)};
|
||||
}
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||
@ -0,0 +1,120 @@
|
||||
// Copyright 2013, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file implements some matchers that depend on gmock-matchers.h.
|
||||
//
|
||||
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
||||
// gmock-more-matchers-test.cc.
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Silence C4100 (unreferenced formal
|
||||
// parameter) for MSVC
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
// and silence C4800 (C4800: 'int *const ': forcing value
|
||||
// to bool 'true' or 'false') for MSVC 14
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Implements the polymorphic IsEmpty matcher, which
|
||||
// can be used as a Matcher<T> as long as T is either a container that defines
|
||||
// empty() and size() (e.g. std::vector or std::string), or a C-style string.
|
||||
class IsEmptyMatcher {
|
||||
public:
|
||||
// Matches anything that defines empty() and size().
|
||||
template <typename MatcheeContainerType>
|
||||
bool MatchAndExplain(const MatcheeContainerType& c,
|
||||
MatchResultListener* listener) const {
|
||||
if (c.empty()) {
|
||||
return true;
|
||||
}
|
||||
*listener << "whose size is " << c.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Matches C-style strings.
|
||||
bool MatchAndExplain(const char* s, MatchResultListener* listener) const {
|
||||
return MatchAndExplain(std::string(s), listener);
|
||||
}
|
||||
|
||||
// Describes what this matcher matches.
|
||||
void DescribeTo(std::ostream* os) const { *os << "is empty"; }
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const { *os << "isn't empty"; }
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Creates a polymorphic matcher that matches an empty container or C-style
|
||||
// string. The container must support both size() and empty(), which all
|
||||
// STL-like containers provide.
|
||||
inline PolymorphicMatcher<internal::IsEmptyMatcher> IsEmpty() {
|
||||
return MakePolymorphicMatcher(internal::IsEmptyMatcher());
|
||||
}
|
||||
|
||||
// Define a matcher that matches a value that evaluates in boolean
|
||||
// context to true. Useful for types that define "explicit operator
|
||||
// bool" operators and so can't be compared for equality with true
|
||||
// and false.
|
||||
MATCHER(IsTrue, negation ? "is false" : "is true") {
|
||||
return static_cast<bool>(arg);
|
||||
}
|
||||
|
||||
// Define a matcher that matches a value that evaluates in boolean
|
||||
// context to false. Useful for types that define "explicit operator
|
||||
// bool" operators and so can't be compared for equality with true
|
||||
// and false.
|
||||
MATCHER(IsFalse, negation ? "is true" : "is false") {
|
||||
return !static_cast<bool>(arg);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||
@ -0,0 +1,277 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Implements class templates NiceMock, NaggyMock, and StrictMock.
|
||||
//
|
||||
// Given a mock class MockFoo that is created using Google Mock,
|
||||
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||
// uninteresting calls (i.e. calls to mock methods that have no
|
||||
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||
// that prints a warning when an uninteresting call occurs, and
|
||||
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||
// uninteresting calls as errors.
|
||||
//
|
||||
// Currently a mock is naggy by default, so MockFoo and
|
||||
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||
// switch the default behavior of mocks to be nice, as that in general
|
||||
// leads to more maintainable tests. When that happens, MockFoo will
|
||||
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||
// NiceMock<MockFoo>.
|
||||
//
|
||||
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
||||
// their respective base class. Therefore you can write
|
||||
// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
|
||||
// has a constructor that accepts (int, const char*), for example.
|
||||
//
|
||||
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
|
||||
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||
// or "strict" modifier may not affect it, depending on the compiler.
|
||||
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||
// supported.
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#include "gmock/gmock-spec-builders.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
namespace testing {
|
||||
template <class MockClass>
|
||||
class NiceMock;
|
||||
template <class MockClass>
|
||||
class NaggyMock;
|
||||
template <class MockClass>
|
||||
class StrictMock;
|
||||
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
std::true_type StrictnessModifierProbe(const NiceMock<T>&);
|
||||
template <typename T>
|
||||
std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
|
||||
template <typename T>
|
||||
std::true_type StrictnessModifierProbe(const StrictMock<T>&);
|
||||
std::false_type StrictnessModifierProbe(...);
|
||||
|
||||
template <typename T>
|
||||
constexpr bool HasStrictnessModifier() {
|
||||
return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
|
||||
}
|
||||
|
||||
// Base classes that register and deregister with testing::Mock to alter the
|
||||
// default behavior around uninteresting calls. Inheriting from one of these
|
||||
// classes first and then MockClass ensures the MockClass constructor is run
|
||||
// after registration, and that the MockClass destructor runs before
|
||||
// deregistration. This guarantees that MockClass's constructor and destructor
|
||||
// run with the same level of strictness as its instance methods.
|
||||
|
||||
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \
|
||||
(defined(_MSC_VER) || defined(__clang__))
|
||||
// We need to mark these classes with this declspec to ensure that
|
||||
// the empty base class optimization is performed.
|
||||
#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)
|
||||
#else
|
||||
#define GTEST_INTERNAL_EMPTY_BASE_CLASS
|
||||
#endif
|
||||
|
||||
template <typename Base>
|
||||
class NiceMockImpl {
|
||||
public:
|
||||
NiceMockImpl() {
|
||||
::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
~NiceMockImpl() {
|
||||
::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class NaggyMockImpl {
|
||||
public:
|
||||
NaggyMockImpl() {
|
||||
::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
~NaggyMockImpl() {
|
||||
::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class StrictMockImpl {
|
||||
public:
|
||||
StrictMockImpl() {
|
||||
::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
~StrictMockImpl() {
|
||||
::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
|
||||
: private internal::NiceMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||
"Can't apply NiceMock to a class hierarchy that already has a "
|
||||
"strictness modifier. See "
|
||||
"https://google.github.io/googletest/"
|
||||
"gmock_cook_book.html#NiceStrictNaggy");
|
||||
NiceMock() : MockClass() {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
// Ideally, we would inherit base class's constructors through a using
|
||||
// declaration, which would preserve their visibility. However, many existing
|
||||
// tests rely on the fact that current implementation reexports protected
|
||||
// constructors as public. These tests would need to be cleaned up first.
|
||||
|
||||
// Single argument constructor is special-cased so that it can be
|
||||
// made explicit.
|
||||
template <typename A>
|
||||
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
template <typename TArg1, typename TArg2, typename... An>
|
||||
NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
|
||||
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
|
||||
std::forward<An>(args)...) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
private:
|
||||
NiceMock(const NiceMock&) = delete;
|
||||
NiceMock& operator=(const NiceMock&) = delete;
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
|
||||
: private internal::NaggyMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
static_assert(!internal::HasStrictnessModifier<MockClass>(),
|
||||
"Can't apply NaggyMock to a class hierarchy that already has a "
|
||||
"strictness modifier. See "
|
||||
"https://google.github.io/googletest/"
|
||||
"gmock_cook_book.html#NiceStrictNaggy");
|
||||
|
||||
public:
|
||||
NaggyMock() : MockClass() {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
// Ideally, we would inherit base class's constructors through a using
|
||||
// declaration, which would preserve their visibility. However, many existing
|
||||
// tests rely on the fact that current implementation reexports protected
|
||||
// constructors as public. These tests would need to be cleaned up first.
|
||||
|
||||
// Single argument constructor is special-cased so that it can be
|
||||
// made explicit.
|
||||
template <typename A>
|
||||
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
template <typename TArg1, typename TArg2, typename... An>
|
||||
NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
|
||||
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
|
||||
std::forward<An>(args)...) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
private:
|
||||
NaggyMock(const NaggyMock&) = delete;
|
||||
NaggyMock& operator=(const NaggyMock&) = delete;
|
||||
};
|
||||
|
||||
template <class MockClass>
|
||||
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
|
||||
: private internal::StrictMockImpl<MockClass>,
|
||||
public MockClass {
|
||||
public:
|
||||
static_assert(
|
||||
!internal::HasStrictnessModifier<MockClass>(),
|
||||
"Can't apply StrictMock to a class hierarchy that already has a "
|
||||
"strictness modifier. See "
|
||||
"https://google.github.io/googletest/"
|
||||
"gmock_cook_book.html#NiceStrictNaggy");
|
||||
StrictMock() : MockClass() {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
// Ideally, we would inherit base class's constructors through a using
|
||||
// declaration, which would preserve their visibility. However, many existing
|
||||
// tests rely on the fact that current implementation reexports protected
|
||||
// constructors as public. These tests would need to be cleaned up first.
|
||||
|
||||
// Single argument constructor is special-cased so that it can be
|
||||
// made explicit.
|
||||
template <typename A>
|
||||
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
template <typename TArg1, typename TArg2, typename... An>
|
||||
StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
|
||||
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
|
||||
std::forward<An>(args)...) {
|
||||
static_assert(sizeof(*this) == sizeof(MockClass),
|
||||
"The impl subclass shouldn't introduce any padding");
|
||||
}
|
||||
|
||||
private:
|
||||
StrictMock(const StrictMock&) = delete;
|
||||
StrictMock& operator=(const StrictMock&) = delete;
|
||||
};
|
||||
|
||||
#undef GTEST_INTERNAL_EMPTY_BASE_CLASS
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,96 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This is the main header file a user should include.
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
|
||||
// This file implements the following syntax:
|
||||
//
|
||||
// ON_CALL(mock_object, Method(...))
|
||||
// .With(...) ?
|
||||
// .WillByDefault(...);
|
||||
//
|
||||
// where With() is optional and WillByDefault() must appear exactly
|
||||
// once.
|
||||
//
|
||||
// EXPECT_CALL(mock_object, Method(...))
|
||||
// .With(...) ?
|
||||
// .Times(...) ?
|
||||
// .InSequence(...) *
|
||||
// .WillOnce(...) *
|
||||
// .WillRepeatedly(...) ?
|
||||
// .RetiresOnSaturation() ? ;
|
||||
//
|
||||
// where all clauses are optional and WillOnce() can be repeated.
|
||||
|
||||
#include "gmock/gmock-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-cardinalities.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-function-mocker.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-actions.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-more-matchers.h" // IWYU pragma: export
|
||||
#include "gmock/gmock-nice-strict.h" // IWYU pragma: export
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
|
||||
// Declares Google Mock flags that we want a user to use programmatically.
|
||||
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||
GMOCK_DECLARE_string_(verbose);
|
||||
GMOCK_DECLARE_int32_(default_mock_behavior);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Initializes Google Mock. This must be called before running the
|
||||
// tests. In particular, it parses the command line for the flags
|
||||
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||
// it is removed from argv, and *argc is decremented.
|
||||
//
|
||||
// No value is returned. Instead, the Google Mock flag variables are
|
||||
// updated.
|
||||
//
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv);
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
|
||||
|
||||
// This overloaded version can be used on Arduino/embedded platforms where
|
||||
// there is no argc/argv.
|
||||
GTEST_API_ void InitGoogleMock();
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||
@ -0,0 +1,18 @@
|
||||
# Customization Points
|
||||
|
||||
The custom directory is an injection point for custom user configurations.
|
||||
|
||||
## Header `gmock-port.h`
|
||||
|
||||
The following macros can be defined:
|
||||
|
||||
### Flag related macros:
|
||||
|
||||
* `GMOCK_DECLARE_bool_(name)`
|
||||
* `GMOCK_DECLARE_int32_(name)`
|
||||
* `GMOCK_DECLARE_string_(name)`
|
||||
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
|
||||
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
|
||||
* `GMOCK_DEFINE_string_(name, default_val, doc)`
|
||||
* `GMOCK_FLAG_GET(flag_name)`
|
||||
* `GMOCK_FLAG_SET(flag_name, value)`
|
||||
@ -0,0 +1,7 @@
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
|
||||
@ -0,0 +1,37 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Injection point for custom user configurations. See README for details
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
|
||||
@ -0,0 +1,40 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Injection point for custom user configurations. See README for details
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
|
||||
@ -0,0 +1,487 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Mock - a framework for writing C++ mock classes.
|
||||
//
|
||||
// This file defines some utilities useful for implementing Google
|
||||
// Mock. They are subject to change without notice, so please DO NOT
|
||||
// USE THEM IN USER CODE.
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
template <typename>
|
||||
class Matcher;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Silence MSVC C4100 (unreferenced formal parameter) and
|
||||
// C4805('==': unsafe mix of type 'const int' and type 'const bool')
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4805)
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
GTEST_API_ std::string JoinAsKeyValueTuple(
|
||||
const std::vector<const char*>& names, const Strings& values);
|
||||
|
||||
// Converts an identifier name to a space-separated list of lower-case
|
||||
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||
// treated as one word. For example, both "FooBar123" and
|
||||
// "foo_bar_123" are converted to "foo bar 123".
|
||||
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
|
||||
|
||||
// GetRawPointer(p) returns the raw pointer underlying p when p is a
|
||||
// smart pointer, or returns p itself when p is already a raw pointer.
|
||||
// The following default implementation is for the smart pointer case.
|
||||
template <typename Pointer>
|
||||
inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
|
||||
return p.get();
|
||||
}
|
||||
// This overload version is for std::reference_wrapper, which does not work with
|
||||
// the overload above, as it does not have an `element_type`.
|
||||
template <typename Element>
|
||||
inline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) {
|
||||
return &r.get();
|
||||
}
|
||||
|
||||
// This overloaded version is for the raw pointer case.
|
||||
template <typename Element>
|
||||
inline Element* GetRawPointer(Element* p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
// Default definitions for all compilers.
|
||||
// NOTE: If you implement support for other compilers, make sure to avoid
|
||||
// unexpected overlaps.
|
||||
// (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.)
|
||||
#define GMOCK_INTERNAL_WARNING_PUSH()
|
||||
#define GMOCK_INTERNAL_WARNING_CLANG(Level, Name)
|
||||
#define GMOCK_INTERNAL_WARNING_POP()
|
||||
|
||||
#if defined(__clang__)
|
||||
#undef GMOCK_INTERNAL_WARNING_PUSH
|
||||
#define GMOCK_INTERNAL_WARNING_PUSH() _Pragma("clang diagnostic push")
|
||||
#undef GMOCK_INTERNAL_WARNING_CLANG
|
||||
#define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \
|
||||
_Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning))
|
||||
#undef GMOCK_INTERNAL_WARNING_POP
|
||||
#define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop")
|
||||
#endif
|
||||
|
||||
// MSVC treats wchar_t as a native type usually, but treats it as the
|
||||
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
||||
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||
// is a native type.
|
||||
#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// wchar_t is a typedef.
|
||||
#else
|
||||
#define GMOCK_WCHAR_T_IS_NATIVE_ 1
|
||||
#endif
|
||||
|
||||
// In what follows, we use the term "kind" to indicate whether a type
|
||||
// is bool, an integer type (excluding bool), a floating-point type,
|
||||
// or none of them. This categorization is useful for determining
|
||||
// when a matcher argument type can be safely converted to another
|
||||
// type in the implementation of SafeMatcherCast.
|
||||
enum TypeKind { kBool, kInteger, kFloatingPoint, kOther };
|
||||
|
||||
// KindOf<T>::value is the kind of type T.
|
||||
template <typename T>
|
||||
struct KindOf {
|
||||
enum { value = kOther }; // The default kind.
|
||||
};
|
||||
|
||||
// This macro declares that the kind of 'type' is 'kind'.
|
||||
#define GMOCK_DECLARE_KIND_(type, kind) \
|
||||
template <> \
|
||||
struct KindOf<type> { \
|
||||
enum { value = kind }; \
|
||||
}
|
||||
|
||||
GMOCK_DECLARE_KIND_(bool, kBool);
|
||||
|
||||
// All standard integer types.
|
||||
GMOCK_DECLARE_KIND_(char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(signed char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
|
||||
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
|
||||
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
|
||||
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
|
||||
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
|
||||
#endif
|
||||
|
||||
// All standard floating-point types.
|
||||
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
|
||||
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
||||
|
||||
#undef GMOCK_DECLARE_KIND_
|
||||
|
||||
// Evaluates to the kind of 'type'.
|
||||
#define GMOCK_KIND_OF_(type) \
|
||||
static_cast< ::testing::internal::TypeKind>( \
|
||||
::testing::internal::KindOf<type>::value)
|
||||
|
||||
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
||||
// is true if and only if arithmetic type From can be losslessly converted to
|
||||
// arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types, kFromKind is the kind of
|
||||
// From, and kToKind is the kind of To; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
||||
using LosslessArithmeticConvertibleImpl = std::integral_constant<
|
||||
bool,
|
||||
// clang-format off
|
||||
// Converting from bool is always lossless
|
||||
(kFromKind == kBool) ? true
|
||||
// Converting between any other type kinds will be lossy if the type
|
||||
// kinds are not the same.
|
||||
: (kFromKind != kToKind) ? false
|
||||
: (kFromKind == kInteger &&
|
||||
// Converting between integers of different widths is allowed so long
|
||||
// as the conversion does not go from signed to unsigned.
|
||||
(((sizeof(From) < sizeof(To)) &&
|
||||
!(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
|
||||
// Converting between integers of the same width only requires the
|
||||
// two types to have the same signedness.
|
||||
((sizeof(From) == sizeof(To)) &&
|
||||
(std::is_signed<From>::value == std::is_signed<To>::value)))
|
||||
) ? true
|
||||
// Floating point conversions are lossless if and only if `To` is at least
|
||||
// as wide as `From`.
|
||||
: (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
|
||||
: false
|
||||
// clang-format on
|
||||
>;
|
||||
|
||||
// LosslessArithmeticConvertible<From, To>::value is true if and only if
|
||||
// arithmetic type From can be losslessly converted to arithmetic type To.
|
||||
//
|
||||
// It's the user's responsibility to ensure that both From and To are
|
||||
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||
// reference) built-in arithmetic types; the value is
|
||||
// implementation-defined when the above pre-condition is violated.
|
||||
template <typename From, typename To>
|
||||
using LosslessArithmeticConvertible =
|
||||
LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
|
||||
GMOCK_KIND_OF_(To), To>;
|
||||
|
||||
// This interface knows how to report a Google Mock failure (either
|
||||
// non-fatal or fatal).
|
||||
class FailureReporterInterface {
|
||||
public:
|
||||
// The type of a failure (either non-fatal or fatal).
|
||||
enum FailureType { kNonfatal, kFatal };
|
||||
|
||||
virtual ~FailureReporterInterface() = default;
|
||||
|
||||
// Reports a failure that occurred at the given source file location.
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const std::string& message) = 0;
|
||||
};
|
||||
|
||||
// Returns the failure reporter used by Google Mock.
|
||||
GTEST_API_ FailureReporterInterface* GetFailureReporter();
|
||||
|
||||
// Asserts that condition is true; aborts the process with the given
|
||||
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
|
||||
// as Google Mock might be used to mock the log sink itself. We
|
||||
// inline this function to prevent it from showing up in the stack
|
||||
// trace.
|
||||
inline void Assert(bool condition, const char* file, int line,
|
||||
const std::string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file,
|
||||
line, msg);
|
||||
}
|
||||
}
|
||||
inline void Assert(bool condition, const char* file, int line) {
|
||||
Assert(condition, file, line, "Assertion failed.");
|
||||
}
|
||||
|
||||
// Verifies that condition is true; generates a non-fatal failure if
|
||||
// condition is false.
|
||||
inline void Expect(bool condition, const char* file, int line,
|
||||
const std::string& msg) {
|
||||
if (!condition) {
|
||||
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
|
||||
file, line, msg);
|
||||
}
|
||||
}
|
||||
inline void Expect(bool condition, const char* file, int line) {
|
||||
Expect(condition, file, line, "Expectation failed.");
|
||||
}
|
||||
|
||||
// Severity level of a log.
|
||||
enum LogSeverity { kInfo = 0, kWarning = 1 };
|
||||
|
||||
// Valid values for the --gmock_verbose flag.
|
||||
|
||||
// All logs (informational and warnings) are printed.
|
||||
const char kInfoVerbosity[] = "info";
|
||||
// Only warnings are printed.
|
||||
const char kWarningVerbosity[] = "warning";
|
||||
// No logs are printed.
|
||||
const char kErrorVerbosity[] = "error";
|
||||
|
||||
// Returns true if and only if a log with the given severity is visible
|
||||
// according to the --gmock_verbose flag.
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
||||
|
||||
// Prints the given message to stdout if and only if 'severity' >= the level
|
||||
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||
// 0, also prints the stack trace excluding the top
|
||||
// stack_frames_to_skip frames. In opt mode, any positive
|
||||
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||
// function calls will be inlined by the compiler and need to be
|
||||
// conservative.
|
||||
GTEST_API_ void Log(LogSeverity severity, const std::string& message,
|
||||
int stack_frames_to_skip);
|
||||
|
||||
// A marker class that is used to resolve parameterless expectations to the
|
||||
// correct overload. This must not be instantiable, to prevent client code from
|
||||
// accidentally resolving to the overload; for example:
|
||||
//
|
||||
// ON_CALL(mock, Method({}, nullptr))...
|
||||
//
|
||||
class WithoutMatchers {
|
||||
private:
|
||||
WithoutMatchers() {}
|
||||
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
};
|
||||
|
||||
// Internal use only: access the singleton instance of WithoutMatchers.
|
||||
GTEST_API_ WithoutMatchers GetWithoutMatchers();
|
||||
|
||||
// Invalid<T>() is usable as an expression of type T, but will terminate
|
||||
// the program with an assertion failure if actually run. This is useful
|
||||
// when a value of type T is needed for compilation, but the statement
|
||||
// will not really be executed (or we don't care if the statement
|
||||
// crashes).
|
||||
template <typename T>
|
||||
inline T Invalid() {
|
||||
Assert(/*condition=*/false, /*file=*/"", /*line=*/-1,
|
||||
"Internal error: attempt to return invalid value");
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER)
|
||||
__assume(0);
|
||||
#else
|
||||
return Invalid<T>();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Given a raw type (i.e. having no top-level reference or const
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
// following members:
|
||||
//
|
||||
// - type is a type that provides an STL-style container view to
|
||||
// (i.e. implements the STL container concept for) RawContainer;
|
||||
// - const_reference is a type that provides a reference to a const
|
||||
// RawContainer;
|
||||
// - ConstReference(raw_container) returns a const reference to an STL-style
|
||||
// container view to raw_container, which is a RawContainer.
|
||||
// - Copy(raw_container) returns an STL-style container view of a
|
||||
// copy of raw_container, which is a RawContainer.
|
||||
//
|
||||
// This generic version is used when RawContainer itself is already an
|
||||
// STL-style container.
|
||||
template <class RawContainer>
|
||||
class StlContainerView {
|
||||
public:
|
||||
typedef RawContainer type;
|
||||
typedef const type& const_reference;
|
||||
|
||||
static const_reference ConstReference(const RawContainer& container) {
|
||||
static_assert(!std::is_const<RawContainer>::value,
|
||||
"RawContainer type must not be const");
|
||||
return container;
|
||||
}
|
||||
static type Copy(const RawContainer& container) { return container; }
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array type.
|
||||
template <typename Element, size_t N>
|
||||
class StlContainerView<Element[N]> {
|
||||
public:
|
||||
typedef typename std::remove_const<Element>::type RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
// NativeArray<T> can represent a native array either by value or by
|
||||
// reference (selected by a constructor argument), so 'const type'
|
||||
// can be used to reference a const native array. We cannot
|
||||
// 'typedef const type& const_reference' here, as that would mean
|
||||
// ConstReference() has to return a reference to a local variable.
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(const Element (&array)[N]) {
|
||||
static_assert(std::is_same<Element, RawElement>::value,
|
||||
"Element type must not be const");
|
||||
return type(array, N, RelationToSourceReference());
|
||||
}
|
||||
static type Copy(const Element (&array)[N]) {
|
||||
return type(array, N, RelationToSourceCopy());
|
||||
}
|
||||
};
|
||||
|
||||
// This specialization is used when RawContainer is a native array
|
||||
// represented as a (pointer, size) tuple.
|
||||
template <typename ElementPointer, typename Size>
|
||||
class StlContainerView< ::std::tuple<ElementPointer, Size> > {
|
||||
public:
|
||||
typedef typename std::remove_const<
|
||||
typename std::pointer_traits<ElementPointer>::element_type>::type
|
||||
RawElement;
|
||||
typedef internal::NativeArray<RawElement> type;
|
||||
typedef const type const_reference;
|
||||
|
||||
static const_reference ConstReference(
|
||||
const ::std::tuple<ElementPointer, Size>& array) {
|
||||
return type(std::get<0>(array), std::get<1>(array),
|
||||
RelationToSourceReference());
|
||||
}
|
||||
static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
|
||||
return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
|
||||
}
|
||||
};
|
||||
|
||||
// The following specialization prevents the user from instantiating
|
||||
// StlContainer with a reference type.
|
||||
template <typename T>
|
||||
class StlContainerView<T&>;
|
||||
|
||||
// A type transform to remove constness from the first part of a pair.
|
||||
// Pairs like that are used as the value_type of associative containers,
|
||||
// and this transform produces a similar but assignable pair.
|
||||
template <typename T>
|
||||
struct RemoveConstFromKey {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// Partially specialized to remove constness from std::pair<const K, V>.
|
||||
template <typename K, typename V>
|
||||
struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||
typedef std::pair<K, V> type;
|
||||
};
|
||||
|
||||
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
|
||||
// reduce code size.
|
||||
GTEST_API_ void IllegalDoDefault(const char* file, int line);
|
||||
|
||||
template <typename F, typename Tuple, size_t... Idx>
|
||||
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
|
||||
-> decltype(std::forward<F>(f)(
|
||||
std::get<Idx>(std::forward<Tuple>(args))...)) {
|
||||
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
|
||||
}
|
||||
|
||||
// Apply the function to a tuple of arguments.
|
||||
template <typename F, typename Tuple>
|
||||
auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
|
||||
std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>())) {
|
||||
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
|
||||
MakeIndexSequence<std::tuple_size<
|
||||
typename std::remove_reference<Tuple>::type>::value>());
|
||||
}
|
||||
|
||||
// Template struct Function<F>, where F must be a function type, contains
|
||||
// the following typedefs:
|
||||
//
|
||||
// Result: the function's return type.
|
||||
// Arg<N>: the type of the N-th argument, where N starts with 0.
|
||||
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||
// parameters of F.
|
||||
// MakeResultVoid: the function type obtained by substituting void
|
||||
// for the return type of F.
|
||||
// MakeResultIgnoredValue:
|
||||
// the function type obtained by substituting Something
|
||||
// for the return type of F.
|
||||
template <typename T>
|
||||
struct Function;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct Function<R(Args...)> {
|
||||
using Result = R;
|
||||
static constexpr size_t ArgumentCount = sizeof...(Args);
|
||||
template <size_t I>
|
||||
using Arg = ElemFromList<I, Args...>;
|
||||
using ArgumentTuple = std::tuple<Args...>;
|
||||
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||
using MakeResultVoid = void(Args...);
|
||||
using MakeResultIgnoredValue = IgnoredValue(Args...);
|
||||
};
|
||||
|
||||
#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
||||
template <typename R, typename... Args>
|
||||
constexpr size_t Function<R(Args...)>::ArgumentCount;
|
||||
#endif
|
||||
|
||||
// Workaround for MSVC error C2039: 'type': is not a member of 'std'
|
||||
// when std::tuple_element is used.
|
||||
// See: https://github.com/google/googletest/issues/3931
|
||||
// Can be replaced with std::tuple_element_t in C++14.
|
||||
template <size_t I, typename T>
|
||||
using TupleElement = typename std::tuple_element<I, T>::type;
|
||||
|
||||
bool Base64Unescape(const std::string& encoded, std::string* decoded);
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4805
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
@ -0,0 +1,139 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Low-level types and utilities for porting Google Mock to various
|
||||
// platforms. All macros ending with _ and symbols defined in an
|
||||
// internal namespace are subject to change without notice. Code
|
||||
// outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't
|
||||
// end with _ are part of Google Mock's public API and can be used by
|
||||
// code outside Google Mock.
|
||||
|
||||
// IWYU pragma: private, include "gmock/gmock.h"
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
// Most of the utilities needed for porting Google Mock are also
|
||||
// required for Google Test and are defined in gtest-port.h.
|
||||
//
|
||||
// Note to maintainers: to reduce code duplication, prefer adding
|
||||
// portability utilities to Google Test's gtest-port.h instead of
|
||||
// here, as Google Mock depends on Google Test. Only add a utility
|
||||
// here if it's truly specific to Google Mock.
|
||||
|
||||
#include "gmock/internal/custom/gmock-port.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#include "absl/flags/declare.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#endif
|
||||
|
||||
// For MS Visual C++, check the compiler version. At least VS 2015 is
|
||||
// required to compile Google Mock.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#error "At least Visual C++ 2015 (14.0) is required to compile Google Mock."
|
||||
#endif
|
||||
|
||||
// Macro for referencing flags. This is public as we want the user to
|
||||
// use this syntax to reference Google Mock flags.
|
||||
#define GMOCK_FLAG_NAME_(name) gmock_##name
|
||||
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||
|
||||
// Pick a command line flags implementation.
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
ABSL_FLAG(bool, GMOCK_FLAG_NAME_(name), default_val, doc)
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
ABSL_FLAG(int32_t, GMOCK_FLAG_NAME_(name), default_val, doc)
|
||||
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
ABSL_FLAG(std::string, GMOCK_FLAG_NAME_(name), default_val, doc)
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) \
|
||||
ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
|
||||
|
||||
#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))
|
||||
#define GMOCK_FLAG_SET(name, value) \
|
||||
(void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
|
||||
|
||||
#else // GTEST_HAS_ABSL
|
||||
|
||||
// Macros for defining flags.
|
||||
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||
namespace testing { \
|
||||
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
|
||||
} \
|
||||
static_assert(true, "no-op to require trailing semicolon")
|
||||
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||
namespace testing { \
|
||||
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \
|
||||
} \
|
||||
static_assert(true, "no-op to require trailing semicolon")
|
||||
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||
namespace testing { \
|
||||
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \
|
||||
} \
|
||||
static_assert(true, "no-op to require trailing semicolon")
|
||||
|
||||
// Macros for declaring flags.
|
||||
#define GMOCK_DECLARE_bool_(name) \
|
||||
namespace testing { \
|
||||
GTEST_API_ extern bool GMOCK_FLAG(name); \
|
||||
} \
|
||||
static_assert(true, "no-op to require trailing semicolon")
|
||||
#define GMOCK_DECLARE_int32_(name) \
|
||||
namespace testing { \
|
||||
GTEST_API_ extern int32_t GMOCK_FLAG(name); \
|
||||
} \
|
||||
static_assert(true, "no-op to require trailing semicolon")
|
||||
#define GMOCK_DECLARE_string_(name) \
|
||||
namespace testing { \
|
||||
GTEST_API_ extern ::std::string GMOCK_FLAG(name); \
|
||||
} \
|
||||
static_assert(true, "no-op to require trailing semicolon")
|
||||
|
||||
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
|
||||
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
|
||||
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||
@ -0,0 +1,279 @@
|
||||
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||
|
||||
// Expands and concatenates the arguments. Constructed macros reevaluate.
|
||||
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
|
||||
|
||||
// Expands and stringifies the only argument.
|
||||
#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)
|
||||
|
||||
// Returns empty. Given a variadic number of arguments.
|
||||
#define GMOCK_PP_EMPTY(...)
|
||||
|
||||
// Returns a comma. Given a variadic number of arguments.
|
||||
#define GMOCK_PP_COMMA(...) ,
|
||||
|
||||
// Returns the only argument.
|
||||
#define GMOCK_PP_IDENTITY(_1) _1
|
||||
|
||||
// Evaluates to the number of arguments after expansion.
|
||||
//
|
||||
// #define PAIR x, y
|
||||
//
|
||||
// GMOCK_PP_NARG() => 1
|
||||
// GMOCK_PP_NARG(x) => 1
|
||||
// GMOCK_PP_NARG(x, y) => 2
|
||||
// GMOCK_PP_NARG(PAIR) => 2
|
||||
//
|
||||
// Requires: the number of arguments after expansion is at most 15.
|
||||
#define GMOCK_PP_NARG(...) \
|
||||
GMOCK_PP_INTERNAL_16TH( \
|
||||
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
||||
|
||||
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
|
||||
// returns 0. Requires no more than 15 unprotected commas.
|
||||
#define GMOCK_PP_HAS_COMMA(...) \
|
||||
GMOCK_PP_INTERNAL_16TH( \
|
||||
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0))
|
||||
|
||||
// Returns the first argument.
|
||||
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg))
|
||||
|
||||
// Returns the tail. A variadic list of all arguments minus the first. Requires
|
||||
// at least one argument.
|
||||
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__))
|
||||
|
||||
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
|
||||
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
|
||||
GMOCK_PP_IDENTITY( \
|
||||
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__))
|
||||
|
||||
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
|
||||
// evaluates to `0`.
|
||||
//
|
||||
// Requires: * the number of arguments after expansion is at most 15.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
//
|
||||
// Implementation details:
|
||||
//
|
||||
// There is one case when it generates a compile error: if the argument is macro
|
||||
// that cannot be called with one argument.
|
||||
//
|
||||
// #define M(a, b) // it doesn't matter what it expands to
|
||||
//
|
||||
// // Expected: expands to `0`.
|
||||
// // Actual: compile error.
|
||||
// GMOCK_PP_IS_EMPTY(M)
|
||||
//
|
||||
// There are 4 cases tested:
|
||||
//
|
||||
// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.
|
||||
// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.
|
||||
// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.
|
||||
// Expected 0
|
||||
// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in
|
||||
// parenthesis, or is a macro that ()-evaluates to comma. Expected 1.
|
||||
//
|
||||
// We trigger detection on '0001', i.e. on empty.
|
||||
#define GMOCK_PP_IS_EMPTY(...) \
|
||||
GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \
|
||||
GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))
|
||||
|
||||
// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.
|
||||
#define GMOCK_PP_IF(_Cond, _Then, _Else) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
|
||||
|
||||
// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses.
|
||||
//
|
||||
// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c
|
||||
// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f
|
||||
//
|
||||
#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \
|
||||
GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else))
|
||||
|
||||
// Evaluates to the number of arguments after expansion. Identifies 'empty' as
|
||||
// 0.
|
||||
//
|
||||
// #define PAIR x, y
|
||||
//
|
||||
// GMOCK_PP_NARG0() => 0
|
||||
// GMOCK_PP_NARG0(x) => 1
|
||||
// GMOCK_PP_NARG0(x, y) => 2
|
||||
// GMOCK_PP_NARG0(PAIR) => 2
|
||||
//
|
||||
// Requires: * the number of arguments after expansion is at most 15.
|
||||
// * If the argument is a macro, it must be able to be called with one
|
||||
// argument.
|
||||
#define GMOCK_PP_NARG0(...) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))
|
||||
|
||||
// Expands to 1 if the first argument starts with something in parentheses,
|
||||
// otherwise to 0.
|
||||
#define GMOCK_PP_IS_BEGIN_PARENS(...) \
|
||||
GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
|
||||
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
|
||||
|
||||
// Expands to 1 is there is only one argument and it is enclosed in parentheses.
|
||||
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
|
||||
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
|
||||
GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)
|
||||
|
||||
// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.
|
||||
#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__
|
||||
|
||||
// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
|
||||
// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
|
||||
// Requires: * |_Macro| can be called with 3 arguments.
|
||||
// * |_Tuple| expansion has no more than 15 elements.
|
||||
#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
|
||||
(0, _Macro, _Data, _Tuple)
|
||||
|
||||
// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
|
||||
// Empty if _K = 0.
|
||||
// Requires: * |_Macro| can be called with 3 arguments.
|
||||
// * |_K| literal between 0 and 15
|
||||
#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \
|
||||
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
|
||||
(0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
|
||||
|
||||
// Increments the argument, requires the argument to be between 0 and 15.
|
||||
#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
|
||||
|
||||
// Returns comma if _i != 0. Requires _i to be between 0 and 15.
|
||||
#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
|
||||
|
||||
// Internal details follow. Do not use any of these symbols outside of this
|
||||
// file or we will break your code.
|
||||
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
|
||||
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
|
||||
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
|
||||
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
|
||||
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
|
||||
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
|
||||
_1, _2, _3, _4))
|
||||
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
|
||||
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
|
||||
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
|
||||
|
||||
// Because of MSVC treating a token with a comma in it as a single token when
|
||||
// passed to another macro, we need to force it to evaluate it as multiple
|
||||
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We
|
||||
// define one per possible macro that relies on this behavior. Note "_Args" must
|
||||
// be parenthesized.
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
|
||||
_10, _11, _12, _13, _14, _15, _16, \
|
||||
...) \
|
||||
_16
|
||||
#define GMOCK_PP_INTERNAL_16TH(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args)
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1
|
||||
#define GMOCK_PP_INTERNAL_HEAD(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args)
|
||||
#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__
|
||||
#define GMOCK_PP_INTERNAL_TAIL(_Args) \
|
||||
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args)
|
||||
|
||||
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
|
||||
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
|
||||
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \
|
||||
0,
|
||||
#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__
|
||||
#define GMOCK_PP_INTERNAL_INC_0 1
|
||||
#define GMOCK_PP_INTERNAL_INC_1 2
|
||||
#define GMOCK_PP_INTERNAL_INC_2 3
|
||||
#define GMOCK_PP_INTERNAL_INC_3 4
|
||||
#define GMOCK_PP_INTERNAL_INC_4 5
|
||||
#define GMOCK_PP_INTERNAL_INC_5 6
|
||||
#define GMOCK_PP_INTERNAL_INC_6 7
|
||||
#define GMOCK_PP_INTERNAL_INC_7 8
|
||||
#define GMOCK_PP_INTERNAL_INC_8 9
|
||||
#define GMOCK_PP_INTERNAL_INC_9 10
|
||||
#define GMOCK_PP_INTERNAL_INC_10 11
|
||||
#define GMOCK_PP_INTERNAL_INC_11 12
|
||||
#define GMOCK_PP_INTERNAL_INC_12 13
|
||||
#define GMOCK_PP_INTERNAL_INC_13 14
|
||||
#define GMOCK_PP_INTERNAL_INC_14 15
|
||||
#define GMOCK_PP_INTERNAL_INC_15 16
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_0
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
|
||||
#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
|
||||
#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
|
||||
_Macro(_i, _Data, _element)
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \
|
||||
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
|
||||
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
|
||||
(GMOCK_PP_TAIL _Tuple))
|
||||
|
||||
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
|
||||
@ -0,0 +1,237 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// This file implements the AssertionResult type.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "gtest/gtest-message.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
// A class for indicating whether an assertion was successful. When
|
||||
// the assertion wasn't successful, the AssertionResult object
|
||||
// remembers a non-empty message that describes how it failed.
|
||||
//
|
||||
// To create an instance of this class, use one of the factory functions
|
||||
// (AssertionSuccess() and AssertionFailure()).
|
||||
//
|
||||
// This class is useful for two purposes:
|
||||
// 1. Defining predicate functions to be used with Boolean test assertions
|
||||
// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
|
||||
// 2. Defining predicate-format functions to be
|
||||
// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
|
||||
//
|
||||
// For example, if you define IsEven predicate:
|
||||
//
|
||||
// testing::AssertionResult IsEven(int n) {
|
||||
// if ((n % 2) == 0)
|
||||
// return testing::AssertionSuccess();
|
||||
// else
|
||||
// return testing::AssertionFailure() << n << " is odd";
|
||||
// }
|
||||
//
|
||||
// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
|
||||
// will print the message
|
||||
//
|
||||
// Value of: IsEven(Fib(5))
|
||||
// Actual: false (5 is odd)
|
||||
// Expected: true
|
||||
//
|
||||
// instead of a more opaque
|
||||
//
|
||||
// Value of: IsEven(Fib(5))
|
||||
// Actual: false
|
||||
// Expected: true
|
||||
//
|
||||
// in case IsEven is a simple Boolean predicate.
|
||||
//
|
||||
// If you expect your predicate to be reused and want to support informative
|
||||
// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
|
||||
// about half as often as positive ones in our tests), supply messages for
|
||||
// both success and failure cases:
|
||||
//
|
||||
// testing::AssertionResult IsEven(int n) {
|
||||
// if ((n % 2) == 0)
|
||||
// return testing::AssertionSuccess() << n << " is even";
|
||||
// else
|
||||
// return testing::AssertionFailure() << n << " is odd";
|
||||
// }
|
||||
//
|
||||
// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
|
||||
//
|
||||
// Value of: IsEven(Fib(6))
|
||||
// Actual: true (8 is even)
|
||||
// Expected: false
|
||||
//
|
||||
// NB: Predicates that support negative Boolean assertions have reduced
|
||||
// performance in positive ones so be careful not to use them in tests
|
||||
// that have lots (tens of thousands) of positive Boolean assertions.
|
||||
//
|
||||
// To use this class with EXPECT_PRED_FORMAT assertions such as:
|
||||
//
|
||||
// // Verifies that Foo() returns an even number.
|
||||
// EXPECT_PRED_FORMAT1(IsEven, Foo());
|
||||
//
|
||||
// you need to define:
|
||||
//
|
||||
// testing::AssertionResult IsEven(const char* expr, int n) {
|
||||
// if ((n % 2) == 0)
|
||||
// return testing::AssertionSuccess();
|
||||
// else
|
||||
// return testing::AssertionFailure()
|
||||
// << "Expected: " << expr << " is even\n Actual: it's " << n;
|
||||
// }
|
||||
//
|
||||
// If Foo() returns 5, you will see the following message:
|
||||
//
|
||||
// Expected: Foo() is even
|
||||
// Actual: it's 5
|
||||
//
|
||||
class GTEST_API_ AssertionResult {
|
||||
public:
|
||||
// Copy constructor.
|
||||
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
||||
AssertionResult(const AssertionResult& other);
|
||||
|
||||
// C4800 is a level 3 warning in Visual Studio 2015 and earlier.
|
||||
// This warning is not emitted in Visual Studio 2017.
|
||||
// This warning is off by default starting in Visual Studio 2019 but can be
|
||||
// enabled with command-line options.
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
|
||||
#endif
|
||||
|
||||
// Used in the EXPECT_TRUE/FALSE(bool_expression).
|
||||
//
|
||||
// T must be contextually convertible to bool.
|
||||
//
|
||||
// The second parameter prevents this overload from being considered if
|
||||
// the argument is implicitly convertible to AssertionResult. In that case
|
||||
// we want AssertionResult's copy constructor to be used.
|
||||
template <typename T>
|
||||
explicit AssertionResult(
|
||||
const T& success,
|
||||
typename std::enable_if<
|
||||
!std::is_convertible<T, AssertionResult>::value>::type*
|
||||
/*enabler*/
|
||||
= nullptr)
|
||||
: success_(success) {}
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||
#endif
|
||||
|
||||
// Assignment operator.
|
||||
AssertionResult& operator=(AssertionResult other) {
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns true if and only if the assertion succeeded.
|
||||
operator bool() const { return success_; } // NOLINT
|
||||
|
||||
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
|
||||
AssertionResult operator!() const;
|
||||
|
||||
// Returns the text streamed into this AssertionResult. Test assertions
|
||||
// use it when they fail (i.e., the predicate's outcome doesn't match the
|
||||
// assertion's expectation). When nothing has been streamed into the
|
||||
// object, returns an empty string.
|
||||
const char* message() const {
|
||||
return message_ != nullptr ? message_->c_str() : "";
|
||||
}
|
||||
// Deprecated; please use message() instead.
|
||||
const char* failure_message() const { return message(); }
|
||||
|
||||
// Streams a custom failure message into this object.
|
||||
template <typename T>
|
||||
AssertionResult& operator<<(const T& value) {
|
||||
AppendMessage(Message() << value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Allows streaming basic output manipulators such as endl or flush into
|
||||
// this object.
|
||||
AssertionResult& operator<<(
|
||||
::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {
|
||||
AppendMessage(Message() << basic_manipulator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// Appends the contents of message to message_.
|
||||
void AppendMessage(const Message& a_message) {
|
||||
if (message_ == nullptr) message_ = ::std::make_unique<::std::string>();
|
||||
message_->append(a_message.GetString().c_str());
|
||||
}
|
||||
|
||||
// Swap the contents of this AssertionResult with other.
|
||||
void swap(AssertionResult& other);
|
||||
|
||||
// Stores result of the assertion predicate.
|
||||
bool success_;
|
||||
// Stores the message describing the condition in case the expectation
|
||||
// construct is not satisfied with the predicate's outcome.
|
||||
// Referenced via a pointer to avoid taking too much stack frame space
|
||||
// with test assertions.
|
||||
std::unique_ptr< ::std::string> message_;
|
||||
};
|
||||
|
||||
// Makes a successful assertion result.
|
||||
GTEST_API_ AssertionResult AssertionSuccess();
|
||||
|
||||
// Makes a failed assertion result.
|
||||
GTEST_API_ AssertionResult AssertionFailure();
|
||||
|
||||
// Makes a failed assertion result with the given failure message.
|
||||
// Deprecated; use AssertionFailure() << msg.
|
||||
GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
|
||||
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
|
||||
@ -0,0 +1,345 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// This header file defines the public API for death tests. It is
|
||||
// #included by gtest.h so a user doesn't need to include this
|
||||
// directly.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
|
||||
#include "gtest/internal/gtest-death-test-internal.h"
|
||||
|
||||
// This flag controls the style of death tests. Valid values are "threadsafe",
|
||||
// meaning that the death test child process will re-execute the test binary
|
||||
// from the start, running only a single death test, or "fast",
|
||||
// meaning that the child process will execute the test logic immediately
|
||||
// after forking.
|
||||
GTEST_DECLARE_string_(death_test_style);
|
||||
|
||||
namespace testing {
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Returns a Boolean value indicating whether the caller is currently
|
||||
// executing in the context of the death test child process. Tools such as
|
||||
// Valgrind heap checkers may need this to modify their behavior in death
|
||||
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||
// implementation of death tests. User code MUST NOT use it.
|
||||
GTEST_API_ bool InDeathTestChild();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The following macros are useful for writing death tests.
|
||||
|
||||
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
|
||||
// executed:
|
||||
//
|
||||
// 1. It generates a warning if there is more than one active
|
||||
// thread. This is because it's safe to fork() or clone() only
|
||||
// when there is a single thread.
|
||||
//
|
||||
// 2. The parent process clone()s a sub-process and runs the death
|
||||
// test in it; the sub-process exits with code 0 at the end of the
|
||||
// death test, if it hasn't exited already.
|
||||
//
|
||||
// 3. The parent process waits for the sub-process to terminate.
|
||||
//
|
||||
// 4. The parent process checks the exit code and error message of
|
||||
// the sub-process.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// EXPECT_DEATH(server.ProcessRequest(i),
|
||||
// "Invalid request .* in ProcessRequest()")
|
||||
// << "Failed to die on request " << i;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
|
||||
//
|
||||
// bool KilledBySIGHUP(int exit_code) {
|
||||
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
|
||||
//
|
||||
// The final parameter to each of these macros is a matcher applied to any data
|
||||
// the sub-process wrote to stderr. For compatibility with existing tests, a
|
||||
// bare string is interpreted as a regular expression matcher.
|
||||
//
|
||||
// On the regular expressions used in death tests:
|
||||
//
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
// On other platforms (e.g. Windows or Mac), we only support a simple regex
|
||||
// syntax implemented as part of Google Test. This limited
|
||||
// implementation should be enough most of the time when writing
|
||||
// death tests; though it lacks many features you can find in PCRE
|
||||
// or POSIX extended regex syntax. For example, we don't support
|
||||
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
||||
// repetition count ("x{5,7}"), among others.
|
||||
//
|
||||
// Below is the syntax that we do support. We chose it to be a
|
||||
// subset of both PCRE and POSIX extended regex, so it's easy to
|
||||
// learn wherever you come from. In the following: 'A' denotes a
|
||||
// literal character, period (.), or a single \\ escape sequence;
|
||||
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
||||
// natural numbers.
|
||||
//
|
||||
// c matches any literal character c
|
||||
// \\d matches any decimal digit
|
||||
// \\D matches any character that's not a decimal digit
|
||||
// \\f matches \f
|
||||
// \\n matches \n
|
||||
// \\r matches \r
|
||||
// \\s matches any ASCII whitespace, including \n
|
||||
// \\S matches any character that's not a whitespace
|
||||
// \\t matches \t
|
||||
// \\v matches \v
|
||||
// \\w matches any letter, _, or decimal digit
|
||||
// \\W matches any character that \\w doesn't match
|
||||
// \\c matches any literal character c, which must be a punctuation
|
||||
// . matches any single character except \n
|
||||
// A? matches 0 or 1 occurrences of A
|
||||
// A* matches 0 or many occurrences of A
|
||||
// A+ matches 1 or many occurrences of A
|
||||
// ^ matches the beginning of a string (not that of each line)
|
||||
// $ matches the end of a string (not that of each line)
|
||||
// xy matches x followed by y
|
||||
//
|
||||
// If you accidentally use PCRE or POSIX extended regex features
|
||||
// not implemented by us, you will get a run-time failure. In that
|
||||
// case, please try to rewrite your regular expression within the
|
||||
// above syntax.
|
||||
//
|
||||
// This implementation is *not* meant to be as highly tuned or robust
|
||||
// as a compiled regex library, but should perform well enough for a
|
||||
// death test, which already incurs significant overhead by launching
|
||||
// a child process.
|
||||
//
|
||||
// Known caveats:
|
||||
//
|
||||
// A "threadsafe" style death test obtains the path to the test
|
||||
// program from argv[0] and re-executes it in the sub-process. For
|
||||
// simplicity, the current implementation doesn't search the PATH
|
||||
// when launching the sub-process. This means that the user must
|
||||
// invoke the test program via a path that contains at least one
|
||||
// path separator (e.g. path/to/foo_test and
|
||||
// /absolute/path/to/bar_test are fine, but foo_test is not). This
|
||||
// is rarely a problem as people usually don't put the test binary
|
||||
// directory in PATH.
|
||||
//
|
||||
|
||||
// Asserts that a given `statement` causes the program to exit, with an
|
||||
// integer exit status that satisfies `predicate`, and emitting error output
|
||||
// that matches `matcher`.
|
||||
#define ASSERT_EXIT(statement, predicate, matcher) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Like `ASSERT_EXIT`, but continues on to successive tests in the
|
||||
// test suite, if any:
|
||||
#define EXPECT_EXIT(statement, predicate, matcher) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_)
|
||||
|
||||
// Asserts that a given `statement` causes the program to exit, either by
|
||||
// explicitly exiting with a nonzero exit code or being killed by a
|
||||
// signal, and emitting error output that matches `matcher`.
|
||||
#define ASSERT_DEATH(statement, matcher) \
|
||||
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
|
||||
|
||||
// Like `ASSERT_DEATH`, but continues on to successive tests in the
|
||||
// test suite, if any:
|
||||
#define EXPECT_DEATH(statement, matcher) \
|
||||
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
|
||||
|
||||
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
||||
|
||||
// Tests that an exit code describes a normal exit with a given exit code.
|
||||
class GTEST_API_ ExitedWithCode {
|
||||
public:
|
||||
explicit ExitedWithCode(int exit_code);
|
||||
ExitedWithCode(const ExitedWithCode&) = default;
|
||||
void operator=(const ExitedWithCode& other) = delete;
|
||||
bool operator()(int exit_status) const;
|
||||
|
||||
private:
|
||||
const int exit_code_;
|
||||
};
|
||||
|
||||
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
|
||||
// Tests that an exit code describes an exit due to termination by a
|
||||
// given signal.
|
||||
class GTEST_API_ KilledBySignal {
|
||||
public:
|
||||
explicit KilledBySignal(int signum);
|
||||
bool operator()(int exit_status) const;
|
||||
|
||||
private:
|
||||
const int signum_;
|
||||
};
|
||||
#endif // !GTEST_OS_WINDOWS
|
||||
|
||||
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
|
||||
// The death testing framework causes this to have interesting semantics,
|
||||
// since the sideeffects of the call are only visible in opt mode, and not
|
||||
// in debug mode.
|
||||
//
|
||||
// In practice, this can be used to test functions that utilize the
|
||||
// LOG(DFATAL) macro using the following style:
|
||||
//
|
||||
// int DieInDebugOr12(int* sideeffect) {
|
||||
// if (sideeffect) {
|
||||
// *sideeffect = 12;
|
||||
// }
|
||||
// LOG(DFATAL) << "death";
|
||||
// return 12;
|
||||
// }
|
||||
//
|
||||
// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {
|
||||
// int sideeffect = 0;
|
||||
// // Only asserts in dbg.
|
||||
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
||||
//
|
||||
// #ifdef NDEBUG
|
||||
// // opt-mode has sideeffect visible.
|
||||
// EXPECT_EQ(12, sideeffect);
|
||||
// #else
|
||||
// // dbg-mode no visible sideeffect.
|
||||
// EXPECT_EQ(0, sideeffect);
|
||||
// #endif
|
||||
// }
|
||||
//
|
||||
// This will assert that DieInDebugReturn12InOpt() crashes in debug
|
||||
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
|
||||
// appropriate fallback value (12 in this case) in opt mode. If you
|
||||
// need to test that a function has appropriate side-effects in opt
|
||||
// mode, include assertions against the side-effects. A general
|
||||
// pattern for this is:
|
||||
//
|
||||
// EXPECT_DEBUG_DEATH({
|
||||
// // Side-effects here will have an effect after this statement in
|
||||
// // opt mode, but none in debug mode.
|
||||
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
|
||||
// }, "death");
|
||||
//
|
||||
#ifdef NDEBUG
|
||||
|
||||
#define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
#define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
#else
|
||||
|
||||
#define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex)
|
||||
|
||||
#define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex)
|
||||
|
||||
#endif // NDEBUG for EXPECT_DEBUG_DEATH
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// This macro is used for implementing macros such as
|
||||
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
||||
// death tests are not supported. Those macros must compile on such systems
|
||||
// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters
|
||||
// on systems that support death tests. This allows one to write such a macro on
|
||||
// a system that does not support death tests and be sure that it will compile
|
||||
// on a death-test supporting system. It is exposed publicly so that systems
|
||||
// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST
|
||||
// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and
|
||||
// ASSERT_DEATH_IF_SUPPORTED.
|
||||
//
|
||||
// Parameters:
|
||||
// statement - A statement that a macro such as EXPECT_DEATH would test
|
||||
// for program termination. This macro has to make sure this
|
||||
// statement is compiled but not executed, to ensure that
|
||||
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||
// parameter if and only if EXPECT_DEATH compiles with it.
|
||||
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||
// the output of statement. This parameter has to be
|
||||
// compiled but not evaluated by this macro, to ensure that
|
||||
// this macro only accepts expressions that a macro such as
|
||||
// EXPECT_DEATH would accept.
|
||||
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
|
||||
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
|
||||
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
|
||||
// compile inside functions where ASSERT_DEATH doesn't
|
||||
// compile.
|
||||
//
|
||||
// The branch that has an always false condition is used to ensure that
|
||||
// statement and regex are compiled (and thus syntactically correct) but
|
||||
// never executed. The unreachable code macro protects the terminator
|
||||
// statement from generating an 'unreachable code' warning in case
|
||||
// statement unconditionally returns or throws. The Message constructor at
|
||||
// the end allows the syntax of streaming additional messages into the
|
||||
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
||||
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
|
||||
<< "Statement '" #statement "' cannot be verified."; \
|
||||
} else if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::RE::PartialMatch(".*", (regex)); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
terminator; \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||
// death tests are supported; otherwise they just issue a warning. This is
|
||||
// useful when you are combining death test assertions with normal test
|
||||
// assertions in one test.
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
#else
|
||||
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
|
||||
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
@ -0,0 +1,923 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// This file implements just enough of the matcher interface to allow
|
||||
// EXPECT_DEATH and friends to accept a matcher argument.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "gtest/gtest-printers.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// MSVC warning C5046 is new as of VS2017 version 15.8.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1915
|
||||
#define GTEST_MAYBE_5046_ 5046
|
||||
#else
|
||||
#define GTEST_MAYBE_5046_
|
||||
#endif
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
||||
4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
|
||||
clients of class B */
|
||||
/* Symbol involving type with internal linkage not defined */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
// To implement a matcher Foo for type T, define:
|
||||
// 1. a class FooMatcherMatcher that implements the matcher interface:
|
||||
// using is_gtest_matcher = void;
|
||||
// bool MatchAndExplain(const T&, std::ostream*);
|
||||
// (MatchResultListener* can also be used instead of std::ostream*)
|
||||
// void DescribeTo(std::ostream*);
|
||||
// void DescribeNegationTo(std::ostream*);
|
||||
//
|
||||
// 2. a factory function that creates a Matcher<T> object from a
|
||||
// FooMatcherMatcher.
|
||||
|
||||
class MatchResultListener {
|
||||
public:
|
||||
// Creates a listener object with the given underlying ostream. The
|
||||
// listener does not own the ostream, and does not dereference it
|
||||
// in the constructor or destructor.
|
||||
explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
|
||||
virtual ~MatchResultListener() = 0; // Makes this class abstract.
|
||||
|
||||
// Streams x to the underlying ostream; does nothing if the ostream
|
||||
// is NULL.
|
||||
template <typename T>
|
||||
MatchResultListener& operator<<(const T& x) {
|
||||
if (stream_ != nullptr) *stream_ << x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns the underlying ostream.
|
||||
::std::ostream* stream() { return stream_; }
|
||||
|
||||
// Returns true if and only if the listener is interested in an explanation
|
||||
// of the match result. A matcher's MatchAndExplain() method can use
|
||||
// this information to avoid generating the explanation when no one
|
||||
// intends to hear it.
|
||||
bool IsInterested() const { return stream_ != nullptr; }
|
||||
|
||||
private:
|
||||
::std::ostream* const stream_;
|
||||
|
||||
MatchResultListener(const MatchResultListener&) = delete;
|
||||
MatchResultListener& operator=(const MatchResultListener&) = delete;
|
||||
};
|
||||
|
||||
inline MatchResultListener::~MatchResultListener() = default;
|
||||
|
||||
// An instance of a subclass of this knows how to describe itself as a
|
||||
// matcher.
|
||||
class GTEST_API_ MatcherDescriberInterface {
|
||||
public:
|
||||
virtual ~MatcherDescriberInterface() = default;
|
||||
|
||||
// Describes this matcher to an ostream. The function should print
|
||||
// a verb phrase that describes the property a value matching this
|
||||
// matcher should have. The subject of the verb phrase is the value
|
||||
// being matched. For example, the DescribeTo() method of the Gt(7)
|
||||
// matcher prints "is greater than 7".
|
||||
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||
|
||||
// Describes the negation of this matcher to an ostream. For
|
||||
// example, if the description of this matcher is "is greater than
|
||||
// 7", the negated description could be "is not greater than 7".
|
||||
// You are not required to override this when implementing
|
||||
// MatcherInterface, but it is highly advised so that your matcher
|
||||
// can produce good error messages.
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "not (";
|
||||
DescribeTo(os);
|
||||
*os << ")";
|
||||
}
|
||||
};
|
||||
|
||||
// The implementation of a matcher.
|
||||
template <typename T>
|
||||
class MatcherInterface : public MatcherDescriberInterface {
|
||||
public:
|
||||
// Returns true if and only if the matcher matches x; also explains the
|
||||
// match result to 'listener' if necessary (see the next paragraph), in
|
||||
// the form of a non-restrictive relative clause ("which ...",
|
||||
// "whose ...", etc) that describes x. For example, the
|
||||
// MatchAndExplain() method of the Pointee(...) matcher should
|
||||
// generate an explanation like "which points to ...".
|
||||
//
|
||||
// Implementations of MatchAndExplain() should add an explanation of
|
||||
// the match result *if and only if* they can provide additional
|
||||
// information that's not already present (or not obvious) in the
|
||||
// print-out of x and the matcher's description. Whether the match
|
||||
// succeeds is not a factor in deciding whether an explanation is
|
||||
// needed, as sometimes the caller needs to print a failure message
|
||||
// when the match succeeds (e.g. when the matcher is used inside
|
||||
// Not()).
|
||||
//
|
||||
// For example, a "has at least 10 elements" matcher should explain
|
||||
// what the actual element count is, regardless of the match result,
|
||||
// as it is useful information to the reader; on the other hand, an
|
||||
// "is empty" matcher probably only needs to explain what the actual
|
||||
// size is when the match fails, as it's redundant to say that the
|
||||
// size is 0 when the value is already known to be empty.
|
||||
//
|
||||
// You should override this method when defining a new matcher.
|
||||
//
|
||||
// It's the responsibility of the caller (Google Test) to guarantee
|
||||
// that 'listener' is not NULL. This helps to simplify a matcher's
|
||||
// implementation when it doesn't care about the performance, as it
|
||||
// can talk to 'listener' without checking its validity first.
|
||||
// However, in order to implement dummy listeners efficiently,
|
||||
// listener->stream() may be NULL.
|
||||
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
|
||||
|
||||
// Inherits these methods from MatcherDescriberInterface:
|
||||
// virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||
// virtual void DescribeNegationTo(::std::ostream* os) const;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// A match result listener that ignores the explanation.
|
||||
class DummyMatchResultListener : public MatchResultListener {
|
||||
public:
|
||||
DummyMatchResultListener() : MatchResultListener(nullptr) {}
|
||||
|
||||
private:
|
||||
DummyMatchResultListener(const DummyMatchResultListener&) = delete;
|
||||
DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;
|
||||
};
|
||||
|
||||
// A match result listener that forwards the explanation to a given
|
||||
// ostream. The difference between this and MatchResultListener is
|
||||
// that the former is concrete.
|
||||
class StreamMatchResultListener : public MatchResultListener {
|
||||
public:
|
||||
explicit StreamMatchResultListener(::std::ostream* os)
|
||||
: MatchResultListener(os) {}
|
||||
|
||||
private:
|
||||
StreamMatchResultListener(const StreamMatchResultListener&) = delete;
|
||||
StreamMatchResultListener& operator=(const StreamMatchResultListener&) =
|
||||
delete;
|
||||
};
|
||||
|
||||
struct SharedPayloadBase {
|
||||
std::atomic<int> ref{1};
|
||||
void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
|
||||
bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SharedPayload : SharedPayloadBase {
|
||||
explicit SharedPayload(const T& v) : value(v) {}
|
||||
explicit SharedPayload(T&& v) : value(std::move(v)) {}
|
||||
|
||||
static void Destroy(SharedPayloadBase* shared) {
|
||||
delete static_cast<SharedPayload*>(shared);
|
||||
}
|
||||
|
||||
T value;
|
||||
};
|
||||
|
||||
// An internal class for implementing Matcher<T>, which will derive
|
||||
// from it. We put functionalities common to all Matcher<T>
|
||||
// specializations here to avoid code duplication.
|
||||
template <typename T>
|
||||
class MatcherBase : private MatcherDescriberInterface {
|
||||
public:
|
||||
// Returns true if and only if the matcher matches x; also explains the
|
||||
// match result to 'listener'.
|
||||
bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
|
||||
GTEST_CHECK_(vtable_ != nullptr);
|
||||
return vtable_->match_and_explain(*this, x, listener);
|
||||
}
|
||||
|
||||
// Returns true if and only if this matcher matches x.
|
||||
bool Matches(const T& x) const {
|
||||
DummyMatchResultListener dummy;
|
||||
return MatchAndExplain(x, &dummy);
|
||||
}
|
||||
|
||||
// Describes this matcher to an ostream.
|
||||
void DescribeTo(::std::ostream* os) const final {
|
||||
GTEST_CHECK_(vtable_ != nullptr);
|
||||
vtable_->describe(*this, os, false);
|
||||
}
|
||||
|
||||
// Describes the negation of this matcher to an ostream.
|
||||
void DescribeNegationTo(::std::ostream* os) const final {
|
||||
GTEST_CHECK_(vtable_ != nullptr);
|
||||
vtable_->describe(*this, os, true);
|
||||
}
|
||||
|
||||
// Explains why x matches, or doesn't match, the matcher.
|
||||
void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
|
||||
StreamMatchResultListener listener(os);
|
||||
MatchAndExplain(x, &listener);
|
||||
}
|
||||
|
||||
// Returns the describer for this matcher object; retains ownership
|
||||
// of the describer, which is only guaranteed to be alive when
|
||||
// this matcher object is alive.
|
||||
const MatcherDescriberInterface* GetDescriber() const {
|
||||
if (vtable_ == nullptr) return nullptr;
|
||||
return vtable_->get_describer(*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
MatcherBase() : vtable_(nullptr), buffer_() {}
|
||||
|
||||
// Constructs a matcher from its implementation.
|
||||
template <typename U>
|
||||
explicit MatcherBase(const MatcherInterface<U>* impl)
|
||||
: vtable_(nullptr), buffer_() {
|
||||
Init(impl);
|
||||
}
|
||||
|
||||
template <typename M, typename = typename std::remove_reference<
|
||||
M>::type::is_gtest_matcher>
|
||||
MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT
|
||||
Init(std::forward<M>(m));
|
||||
}
|
||||
|
||||
MatcherBase(const MatcherBase& other)
|
||||
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
||||
if (IsShared()) buffer_.shared->Ref();
|
||||
}
|
||||
|
||||
MatcherBase& operator=(const MatcherBase& other) {
|
||||
if (this == &other) return *this;
|
||||
Destroy();
|
||||
vtable_ = other.vtable_;
|
||||
buffer_ = other.buffer_;
|
||||
if (IsShared()) buffer_.shared->Ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
MatcherBase(MatcherBase&& other)
|
||||
: vtable_(other.vtable_), buffer_(other.buffer_) {
|
||||
other.vtable_ = nullptr;
|
||||
}
|
||||
|
||||
MatcherBase& operator=(MatcherBase&& other) {
|
||||
if (this == &other) return *this;
|
||||
Destroy();
|
||||
vtable_ = other.vtable_;
|
||||
buffer_ = other.buffer_;
|
||||
other.vtable_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~MatcherBase() override { Destroy(); }
|
||||
|
||||
private:
|
||||
struct VTable {
|
||||
bool (*match_and_explain)(const MatcherBase&, const T&,
|
||||
MatchResultListener*);
|
||||
void (*describe)(const MatcherBase&, std::ostream*, bool negation);
|
||||
// Returns the captured object if it implements the interface, otherwise
|
||||
// returns the MatcherBase itself.
|
||||
const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);
|
||||
// Called on shared instances when the reference count reaches 0.
|
||||
void (*shared_destroy)(SharedPayloadBase*);
|
||||
};
|
||||
|
||||
bool IsShared() const {
|
||||
return vtable_ != nullptr && vtable_->shared_destroy != nullptr;
|
||||
}
|
||||
|
||||
// If the implementation uses a listener, call that.
|
||||
template <typename P>
|
||||
static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
|
||||
MatchResultListener* listener)
|
||||
-> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
|
||||
return P::Get(m).MatchAndExplain(value, listener->stream());
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
|
||||
MatchResultListener* listener)
|
||||
-> decltype(P::Get(m).MatchAndExplain(value, listener)) {
|
||||
return P::Get(m).MatchAndExplain(value, listener);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static void DescribeImpl(const MatcherBase& m, std::ostream* os,
|
||||
bool negation) {
|
||||
if (negation) {
|
||||
P::Get(m).DescribeNegationTo(os);
|
||||
} else {
|
||||
P::Get(m).DescribeTo(os);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static const MatcherDescriberInterface* GetDescriberImpl(
|
||||
const MatcherBase& m) {
|
||||
// If the impl is a MatcherDescriberInterface, then return it.
|
||||
// Otherwise use MatcherBase itself.
|
||||
// This allows us to implement the GetDescriber() function without support
|
||||
// from the impl, but some users really want to get their impl back when
|
||||
// they call GetDescriber().
|
||||
// We use std::get on a tuple as a workaround of not having `if constexpr`.
|
||||
return std::get<(
|
||||
std::is_convertible<decltype(&P::Get(m)),
|
||||
const MatcherDescriberInterface*>::value
|
||||
? 1
|
||||
: 0)>(std::make_tuple(&m, &P::Get(m)));
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
const VTable* GetVTable() {
|
||||
static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
|
||||
&DescribeImpl<P>, &GetDescriberImpl<P>,
|
||||
P::shared_destroy};
|
||||
return &kVTable;
|
||||
}
|
||||
|
||||
union Buffer {
|
||||
// Add some types to give Buffer some common alignment/size use cases.
|
||||
void* ptr;
|
||||
double d;
|
||||
int64_t i;
|
||||
// And add one for the out-of-line cases.
|
||||
SharedPayloadBase* shared;
|
||||
};
|
||||
|
||||
void Destroy() {
|
||||
if (IsShared() && buffer_.shared->Unref()) {
|
||||
vtable_->shared_destroy(buffer_.shared);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
static constexpr bool IsInlined() {
|
||||
return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
|
||||
std::is_trivially_copy_constructible<M>::value &&
|
||||
std::is_trivially_destructible<M>::value;
|
||||
}
|
||||
|
||||
template <typename M, bool = MatcherBase::IsInlined<M>()>
|
||||
struct ValuePolicy {
|
||||
static const M& Get(const MatcherBase& m) {
|
||||
// When inlined along with Init, need to be explicit to avoid violating
|
||||
// strict aliasing rules.
|
||||
const M* ptr =
|
||||
static_cast<const M*>(static_cast<const void*>(&m.buffer_));
|
||||
return *ptr;
|
||||
}
|
||||
static void Init(MatcherBase& m, M impl) {
|
||||
::new (static_cast<void*>(&m.buffer_)) M(impl);
|
||||
}
|
||||
static constexpr auto shared_destroy = nullptr;
|
||||
};
|
||||
|
||||
template <typename M>
|
||||
struct ValuePolicy<M, false> {
|
||||
using Shared = SharedPayload<M>;
|
||||
static const M& Get(const MatcherBase& m) {
|
||||
return static_cast<Shared*>(m.buffer_.shared)->value;
|
||||
}
|
||||
template <typename Arg>
|
||||
static void Init(MatcherBase& m, Arg&& arg) {
|
||||
m.buffer_.shared = new Shared(std::forward<Arg>(arg));
|
||||
}
|
||||
static constexpr auto shared_destroy = &Shared::Destroy;
|
||||
};
|
||||
|
||||
template <typename U, bool B>
|
||||
struct ValuePolicy<const MatcherInterface<U>*, B> {
|
||||
using M = const MatcherInterface<U>;
|
||||
using Shared = SharedPayload<std::unique_ptr<M>>;
|
||||
static const M& Get(const MatcherBase& m) {
|
||||
return *static_cast<Shared*>(m.buffer_.shared)->value;
|
||||
}
|
||||
static void Init(MatcherBase& m, M* impl) {
|
||||
m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));
|
||||
}
|
||||
|
||||
static constexpr auto shared_destroy = &Shared::Destroy;
|
||||
};
|
||||
|
||||
template <typename M>
|
||||
void Init(M&& m) {
|
||||
using MM = typename std::decay<M>::type;
|
||||
using Policy = ValuePolicy<MM>;
|
||||
vtable_ = GetVTable<Policy>();
|
||||
Policy::Init(*this, std::forward<M>(m));
|
||||
}
|
||||
|
||||
const VTable* vtable_;
|
||||
Buffer buffer_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
|
||||
// object that can check whether a value of type T matches. The
|
||||
// implementation of Matcher<T> is just a std::shared_ptr to const
|
||||
// MatcherInterface<T>. Don't inherit from Matcher!
|
||||
template <typename T>
|
||||
class Matcher : public internal::MatcherBase<T> {
|
||||
public:
|
||||
// Constructs a null matcher. Needed for storing Matcher objects in STL
|
||||
// containers. A default-constructed matcher is not yet initialized. You
|
||||
// cannot use it until a valid value has been assigned to it.
|
||||
explicit Matcher() {} // NOLINT
|
||||
|
||||
// Constructs a matcher from its implementation.
|
||||
explicit Matcher(const MatcherInterface<const T&>* impl)
|
||||
: internal::MatcherBase<T>(impl) {}
|
||||
|
||||
template <typename U>
|
||||
explicit Matcher(
|
||||
const MatcherInterface<U>* impl,
|
||||
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
|
||||
nullptr)
|
||||
: internal::MatcherBase<T>(impl) {}
|
||||
|
||||
template <typename M, typename = typename std::remove_reference<
|
||||
M>::type::is_gtest_matcher>
|
||||
Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT
|
||||
|
||||
// Implicit constructor here allows people to write
|
||||
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
|
||||
Matcher(T value); // NOLINT
|
||||
};
|
||||
|
||||
// The following two specializations allow the user to write str
|
||||
// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
|
||||
// matcher is expected.
|
||||
template <>
|
||||
class GTEST_API_ Matcher<const std::string&>
|
||||
: public internal::MatcherBase<const std::string&> {
|
||||
public:
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||
: internal::MatcherBase<const std::string&>(impl) {}
|
||||
|
||||
template <typename M, typename = typename std::remove_reference<
|
||||
M>::type::is_gtest_matcher>
|
||||
Matcher(M&& m) // NOLINT
|
||||
: internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
|
||||
|
||||
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||
// str is a std::string object.
|
||||
Matcher(const std::string& s); // NOLINT
|
||||
|
||||
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||
Matcher(const char* s); // NOLINT
|
||||
};
|
||||
|
||||
template <>
|
||||
class GTEST_API_ Matcher<std::string>
|
||||
: public internal::MatcherBase<std::string> {
|
||||
public:
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const std::string&>* impl)
|
||||
: internal::MatcherBase<std::string>(impl) {}
|
||||
explicit Matcher(const MatcherInterface<std::string>* impl)
|
||||
: internal::MatcherBase<std::string>(impl) {}
|
||||
|
||||
template <typename M, typename = typename std::remove_reference<
|
||||
M>::type::is_gtest_matcher>
|
||||
Matcher(M&& m) // NOLINT
|
||||
: internal::MatcherBase<std::string>(std::forward<M>(m)) {}
|
||||
|
||||
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||
// str is a string object.
|
||||
Matcher(const std::string& s); // NOLINT
|
||||
|
||||
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||
Matcher(const char* s); // NOLINT
|
||||
};
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
// The following two specializations allow the user to write str
|
||||
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
|
||||
// matcher is expected.
|
||||
template <>
|
||||
class GTEST_API_ Matcher<const internal::StringView&>
|
||||
: public internal::MatcherBase<const internal::StringView&> {
|
||||
public:
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
||||
: internal::MatcherBase<const internal::StringView&>(impl) {}
|
||||
|
||||
template <typename M, typename = typename std::remove_reference<
|
||||
M>::type::is_gtest_matcher>
|
||||
Matcher(M&& m) // NOLINT
|
||||
: internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
|
||||
}
|
||||
|
||||
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||
// str is a std::string object.
|
||||
Matcher(const std::string& s); // NOLINT
|
||||
|
||||
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||
Matcher(const char* s); // NOLINT
|
||||
|
||||
// Allows the user to pass absl::string_views or std::string_views directly.
|
||||
Matcher(internal::StringView s); // NOLINT
|
||||
};
|
||||
|
||||
template <>
|
||||
class GTEST_API_ Matcher<internal::StringView>
|
||||
: public internal::MatcherBase<internal::StringView> {
|
||||
public:
|
||||
Matcher() = default;
|
||||
|
||||
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
|
||||
: internal::MatcherBase<internal::StringView>(impl) {}
|
||||
explicit Matcher(const MatcherInterface<internal::StringView>* impl)
|
||||
: internal::MatcherBase<internal::StringView>(impl) {}
|
||||
|
||||
template <typename M, typename = typename std::remove_reference<
|
||||
M>::type::is_gtest_matcher>
|
||||
Matcher(M&& m) // NOLINT
|
||||
: internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
|
||||
|
||||
// Allows the user to write str instead of Eq(str) sometimes, where
|
||||
// str is a std::string object.
|
||||
Matcher(const std::string& s); // NOLINT
|
||||
|
||||
// Allows the user to write "foo" instead of Eq("foo") sometimes.
|
||||
Matcher(const char* s); // NOLINT
|
||||
|
||||
// Allows the user to pass absl::string_views or std::string_views directly.
|
||||
Matcher(internal::StringView s); // NOLINT
|
||||
};
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
|
||||
// Prints a matcher in a human-readable format.
|
||||
template <typename T>
|
||||
std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
|
||||
matcher.DescribeTo(&os);
|
||||
return os;
|
||||
}
|
||||
|
||||
// The PolymorphicMatcher class template makes it easy to implement a
|
||||
// polymorphic matcher (i.e. a matcher that can match values of more
|
||||
// than one type, e.g. Eq(n) and NotNull()).
|
||||
//
|
||||
// To define a polymorphic matcher, a user should provide an Impl
|
||||
// class that has a DescribeTo() method and a DescribeNegationTo()
|
||||
// method, and define a member function (or member function template)
|
||||
//
|
||||
// bool MatchAndExplain(const Value& value,
|
||||
// MatchResultListener* listener) const;
|
||||
//
|
||||
// See the definition of NotNull() for a complete example.
|
||||
template <class Impl>
|
||||
class PolymorphicMatcher {
|
||||
public:
|
||||
explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
|
||||
|
||||
// Returns a mutable reference to the underlying matcher
|
||||
// implementation object.
|
||||
Impl& mutable_impl() { return impl_; }
|
||||
|
||||
// Returns an immutable reference to the underlying matcher
|
||||
// implementation object.
|
||||
const Impl& impl() const { return impl_; }
|
||||
|
||||
template <typename T>
|
||||
operator Matcher<T>() const {
|
||||
return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
class MonomorphicImpl : public MatcherInterface<T> {
|
||||
public:
|
||||
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
|
||||
|
||||
void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); }
|
||||
|
||||
void DescribeNegationTo(::std::ostream* os) const override {
|
||||
impl_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
bool MatchAndExplain(T x, MatchResultListener* listener) const override {
|
||||
return impl_.MatchAndExplain(x, listener);
|
||||
}
|
||||
|
||||
private:
|
||||
const Impl impl_;
|
||||
};
|
||||
|
||||
Impl impl_;
|
||||
};
|
||||
|
||||
// Creates a matcher from its implementation.
|
||||
// DEPRECATED: Especially in the generic code, prefer:
|
||||
// Matcher<T>(new MyMatcherImpl<const T&>(...));
|
||||
//
|
||||
// MakeMatcher may create a Matcher that accepts its argument by value, which
|
||||
// leads to unnecessary copies & lack of support for non-copyable types.
|
||||
template <typename T>
|
||||
inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
|
||||
return Matcher<T>(impl);
|
||||
}
|
||||
|
||||
// Creates a polymorphic matcher from its implementation. This is
|
||||
// easier to use than the PolymorphicMatcher<Impl> constructor as it
|
||||
// doesn't require you to explicitly write the template argument, e.g.
|
||||
//
|
||||
// MakePolymorphicMatcher(foo);
|
||||
// vs
|
||||
// PolymorphicMatcher<TypeOfFoo>(foo);
|
||||
template <class Impl>
|
||||
inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
|
||||
return PolymorphicMatcher<Impl>(impl);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
// Implements a matcher that compares a given value with a
|
||||
// pre-supplied value using one of the ==, <=, <, etc, operators. The
|
||||
// two values being compared don't have to have the same type.
|
||||
//
|
||||
// The matcher defined here is polymorphic (for example, Eq(5) can be
|
||||
// used to match an int, a short, a double, etc). Therefore we use
|
||||
// a template type conversion operator in the implementation.
|
||||
//
|
||||
// The following template definition assumes that the Rhs parameter is
|
||||
// a "bare" type (i.e. neither 'const T' nor 'T&').
|
||||
template <typename D, typename Rhs, typename Op>
|
||||
class ComparisonBase {
|
||||
public:
|
||||
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
|
||||
|
||||
using is_gtest_matcher = void;
|
||||
|
||||
template <typename Lhs>
|
||||
bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
|
||||
return Op()(lhs, Unwrap(rhs_));
|
||||
}
|
||||
void DescribeTo(std::ostream* os) const {
|
||||
*os << D::Desc() << " ";
|
||||
UniversalPrint(Unwrap(rhs_), os);
|
||||
}
|
||||
void DescribeNegationTo(std::ostream* os) const {
|
||||
*os << D::NegatedDesc() << " ";
|
||||
UniversalPrint(Unwrap(rhs_), os);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static const T& Unwrap(const T& v) {
|
||||
return v;
|
||||
}
|
||||
template <typename T>
|
||||
static const T& Unwrap(std::reference_wrapper<T> v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
Rhs rhs_;
|
||||
};
|
||||
|
||||
template <typename Rhs>
|
||||
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
|
||||
public:
|
||||
explicit EqMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
|
||||
static const char* Desc() { return "is equal to"; }
|
||||
static const char* NegatedDesc() { return "isn't equal to"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class NeMatcher
|
||||
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
|
||||
public:
|
||||
explicit NeMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>>(rhs) {}
|
||||
static const char* Desc() { return "isn't equal to"; }
|
||||
static const char* NegatedDesc() { return "is equal to"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
|
||||
public:
|
||||
explicit LtMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
|
||||
static const char* Desc() { return "is <"; }
|
||||
static const char* NegatedDesc() { return "isn't <"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
|
||||
public:
|
||||
explicit GtMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
|
||||
static const char* Desc() { return "is >"; }
|
||||
static const char* NegatedDesc() { return "isn't >"; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class LeMatcher
|
||||
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
|
||||
public:
|
||||
explicit LeMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>>(rhs) {}
|
||||
static const char* Desc() { return "is <="; }
|
||||
static const char* NegatedDesc() { return "isn't <="; }
|
||||
};
|
||||
template <typename Rhs>
|
||||
class GeMatcher
|
||||
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
|
||||
public:
|
||||
explicit GeMatcher(const Rhs& rhs)
|
||||
: ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>>(rhs) {}
|
||||
static const char* Desc() { return "is >="; }
|
||||
static const char* NegatedDesc() { return "isn't >="; }
|
||||
};
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
std::is_constructible<std::string, T>::value>::type>
|
||||
using StringLike = T;
|
||||
|
||||
// Implements polymorphic matchers MatchesRegex(regex) and
|
||||
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
|
||||
// T can be converted to a string.
|
||||
class MatchesRegexMatcher {
|
||||
public:
|
||||
MatchesRegexMatcher(const RE* regex, bool full_match)
|
||||
: regex_(regex), full_match_(full_match) {}
|
||||
|
||||
#if GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
bool MatchAndExplain(const internal::StringView& s,
|
||||
MatchResultListener* listener) const {
|
||||
return MatchAndExplain(std::string(s), listener);
|
||||
}
|
||||
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
|
||||
|
||||
// Accepts pointer types, particularly:
|
||||
// const char*
|
||||
// char*
|
||||
// const wchar_t*
|
||||
// wchar_t*
|
||||
template <typename CharType>
|
||||
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
|
||||
return s != nullptr && MatchAndExplain(std::string(s), listener);
|
||||
}
|
||||
|
||||
// Matches anything that can convert to std::string.
|
||||
//
|
||||
// This is a template, not just a plain function with const std::string&,
|
||||
// because absl::string_view has some interfering non-explicit constructors.
|
||||
template <class MatcheeStringType>
|
||||
bool MatchAndExplain(const MatcheeStringType& s,
|
||||
MatchResultListener* /* listener */) const {
|
||||
const std::string s2(s);
|
||||
return full_match_ ? RE::FullMatch(s2, *regex_)
|
||||
: RE::PartialMatch(s2, *regex_);
|
||||
}
|
||||
|
||||
void DescribeTo(::std::ostream* os) const {
|
||||
*os << (full_match_ ? "matches" : "contains") << " regular expression ";
|
||||
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "doesn't " << (full_match_ ? "match" : "contain")
|
||||
<< " regular expression ";
|
||||
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::shared_ptr<const RE> regex_;
|
||||
const bool full_match_;
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
// Matches a string that fully matches regular expression 'regex'.
|
||||
// The matcher takes ownership of 'regex'.
|
||||
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
||||
const internal::RE* regex) {
|
||||
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
|
||||
}
|
||||
template <typename T = std::string>
|
||||
PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
|
||||
const internal::StringLike<T>& regex) {
|
||||
return MatchesRegex(new internal::RE(std::string(regex)));
|
||||
}
|
||||
|
||||
// Matches a string that contains regular expression 'regex'.
|
||||
// The matcher takes ownership of 'regex'.
|
||||
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
||||
const internal::RE* regex) {
|
||||
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
|
||||
}
|
||||
template <typename T = std::string>
|
||||
PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
|
||||
const internal::StringLike<T>& regex) {
|
||||
return ContainsRegex(new internal::RE(std::string(regex)));
|
||||
}
|
||||
|
||||
// Creates a polymorphic matcher that matches anything equal to x.
|
||||
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
|
||||
// wouldn't compile.
|
||||
template <typename T>
|
||||
inline internal::EqMatcher<T> Eq(T x) {
|
||||
return internal::EqMatcher<T>(x);
|
||||
}
|
||||
|
||||
// Constructs a Matcher<T> from a 'value' of type T. The constructed
|
||||
// matcher matches any value that's equal to 'value'.
|
||||
template <typename T>
|
||||
Matcher<T>::Matcher(T value) {
|
||||
*this = Eq(value);
|
||||
}
|
||||
|
||||
// Creates a monomorphic matcher that matches anything with type Lhs
|
||||
// and equal to rhs. A user may need to use this instead of Eq(...)
|
||||
// in order to resolve an overloading ambiguity.
|
||||
//
|
||||
// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
|
||||
// or Matcher<T>(x), but more readable than the latter.
|
||||
//
|
||||
// We could define similar monomorphic matchers for other comparison
|
||||
// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
|
||||
// it yet as those are used much less than Eq() in practice. A user
|
||||
// can always write Matcher<T>(Lt(5)) to be explicit about the type,
|
||||
// for example.
|
||||
template <typename Lhs, typename Rhs>
|
||||
inline Matcher<Lhs> TypedEq(const Rhs& rhs) {
|
||||
return Eq(rhs);
|
||||
}
|
||||
|
||||
// Creates a polymorphic matcher that matches anything >= x.
|
||||
template <typename Rhs>
|
||||
inline internal::GeMatcher<Rhs> Ge(Rhs x) {
|
||||
return internal::GeMatcher<Rhs>(x);
|
||||
}
|
||||
|
||||
// Creates a polymorphic matcher that matches anything > x.
|
||||
template <typename Rhs>
|
||||
inline internal::GtMatcher<Rhs> Gt(Rhs x) {
|
||||
return internal::GtMatcher<Rhs>(x);
|
||||
}
|
||||
|
||||
// Creates a polymorphic matcher that matches anything <= x.
|
||||
template <typename Rhs>
|
||||
inline internal::LeMatcher<Rhs> Le(Rhs x) {
|
||||
return internal::LeMatcher<Rhs>(x);
|
||||
}
|
||||
|
||||
// Creates a polymorphic matcher that matches anything < x.
|
||||
template <typename Rhs>
|
||||
inline internal::LtMatcher<Rhs> Lt(Rhs x) {
|
||||
return internal::LtMatcher<Rhs>(x);
|
||||
}
|
||||
|
||||
// Creates a polymorphic matcher that matches anything != x.
|
||||
template <typename Rhs>
|
||||
inline internal::NeMatcher<Rhs> Ne(Rhs x) {
|
||||
return internal::NeMatcher<Rhs>(x);
|
||||
}
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
|
||||
@ -0,0 +1,251 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// This header file defines the Message class.
|
||||
//
|
||||
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
||||
// leave some internal implementation details in this header file.
|
||||
// They are clearly marked by comments like this:
|
||||
//
|
||||
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
//
|
||||
// Such code is NOT meant to be used by a user directly, and is subject
|
||||
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||
// program!
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/strings/has_absl_stringify.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
// Ensures that there is at least one operator<< in the global namespace.
|
||||
// See Message& operator<<(...) below for why.
|
||||
void operator<<(const testing::internal::Secret&, int);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The Message class works like an ostream repeater.
|
||||
//
|
||||
// Typical usage:
|
||||
//
|
||||
// 1. You stream a bunch of values to a Message object.
|
||||
// It will remember the text in a stringstream.
|
||||
// 2. Then you stream the Message object to an ostream.
|
||||
// This causes the text in the Message to be streamed
|
||||
// to the ostream.
|
||||
//
|
||||
// For example;
|
||||
//
|
||||
// testing::Message foo;
|
||||
// foo << 1 << " != " << 2;
|
||||
// std::cout << foo;
|
||||
//
|
||||
// will print "1 != 2".
|
||||
//
|
||||
// Message is not intended to be inherited from. In particular, its
|
||||
// destructor is not virtual.
|
||||
//
|
||||
// Note that stringstream behaves differently in gcc and in MSVC. You
|
||||
// can stream a NULL char pointer to it in the former, but not in the
|
||||
// latter (it causes an access violation if you do). The Message
|
||||
// class hides this difference by treating a NULL char pointer as
|
||||
// "(null)".
|
||||
class GTEST_API_ Message {
|
||||
private:
|
||||
// The type of basic IO manipulators (endl, ends, and flush) for
|
||||
// narrow streams.
|
||||
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
|
||||
|
||||
public:
|
||||
// Constructs an empty Message.
|
||||
Message();
|
||||
|
||||
// Copy constructor.
|
||||
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
|
||||
*ss_ << msg.GetString();
|
||||
}
|
||||
|
||||
// Constructs a Message from a C-string.
|
||||
explicit Message(const char* str) : ss_(new ::std::stringstream) {
|
||||
*ss_ << str;
|
||||
}
|
||||
|
||||
// Streams a non-pointer value to this object. If building a version of
|
||||
// GoogleTest with ABSL, this overload is only enabled if the value does not
|
||||
// have an AbslStringify definition.
|
||||
template <
|
||||
typename T
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
,
|
||||
typename std::enable_if<!absl::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0
|
||||
#endif // GTEST_HAS_ABSL
|
||||
>
|
||||
inline Message& operator<<(const T& val) {
|
||||
// Some libraries overload << for STL containers. These
|
||||
// overloads are defined in the global namespace instead of ::std.
|
||||
//
|
||||
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
|
||||
// overloads are visible in either the std namespace or the global
|
||||
// namespace, but not other namespaces, including the testing
|
||||
// namespace which Google Test's Message class is in.
|
||||
//
|
||||
// To allow STL containers (and other types that has a << operator
|
||||
// defined in the global namespace) to be used in Google Test
|
||||
// assertions, testing::Message must access the custom << operator
|
||||
// from the global namespace. With this using declaration,
|
||||
// overloads of << defined in the global namespace and those
|
||||
// visible via Koenig lookup are both exposed in this function.
|
||||
using ::operator<<;
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_ABSL
|
||||
// Streams a non-pointer value with an AbslStringify definition to this
|
||||
// object.
|
||||
template <typename T,
|
||||
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
|
||||
int>::type = 0>
|
||||
inline Message& operator<<(const T& val) {
|
||||
// ::operator<< is needed here for a similar reason as with the non-Abseil
|
||||
// version above
|
||||
using ::operator<<;
|
||||
*ss_ << absl::StrCat(val);
|
||||
return *this;
|
||||
}
|
||||
#endif // GTEST_HAS_ABSL
|
||||
|
||||
// Streams a pointer value to this object.
|
||||
//
|
||||
// This function is an overload of the previous one. When you
|
||||
// stream a pointer to a Message, this definition will be used as it
|
||||
// is more specialized. (The C++ Standard, section
|
||||
// [temp.func.order].) If you stream a non-pointer, then the
|
||||
// previous definition will be used.
|
||||
//
|
||||
// The reason for this overload is that streaming a NULL pointer to
|
||||
// ostream is undefined behavior. Depending on the compiler, you
|
||||
// may get "0", "(nil)", "(null)", or an access violation. To
|
||||
// ensure consistent result across compilers, we always treat NULL
|
||||
// as "(null)".
|
||||
template <typename T>
|
||||
inline Message& operator<<(T* const& pointer) { // NOLINT
|
||||
if (pointer == nullptr) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
*ss_ << pointer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Since the basic IO manipulators are overloaded for both narrow
|
||||
// and wide streams, we have to provide this specialized definition
|
||||
// of operator <<, even though its body is the same as the
|
||||
// templatized version above. Without this definition, streaming
|
||||
// endl or other basic IO manipulators to Message will confuse the
|
||||
// compiler.
|
||||
Message& operator<<(BasicNarrowIoManip val) {
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Instead of 1/0, we want to see true/false for bool values.
|
||||
Message& operator<<(bool b) { return *this << (b ? "true" : "false"); }
|
||||
|
||||
// These two overloads allow streaming a wide C string to a Message
|
||||
// using the UTF-8 encoding.
|
||||
Message& operator<<(const wchar_t* wide_c_str);
|
||||
Message& operator<<(wchar_t* wide_c_str);
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Converts the given wide string to a narrow string using the UTF-8
|
||||
// encoding, and streams the result to this Message object.
|
||||
Message& operator<<(const ::std::wstring& wstr);
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Gets the text streamed to this object so far as an std::string.
|
||||
// Each '\0' character in the buffer is replaced with "\\0".
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
std::string GetString() const;
|
||||
|
||||
private:
|
||||
// We'll hold the text streamed to this object here.
|
||||
const std::unique_ptr< ::std::stringstream> ss_;
|
||||
|
||||
// We declare (but don't implement) this to prevent the compiler
|
||||
// from implementing the assignment operator.
|
||||
void operator=(const Message&);
|
||||
};
|
||||
|
||||
// Streams a Message to an ostream.
|
||||
inline std::ostream& operator<<(std::ostream& os, const Message& sb) {
|
||||
return os << sb.GetString();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Converts a streamable value to an std::string. A NULL pointer is
|
||||
// converted to "(null)". When the input value is a ::string,
|
||||
// ::std::string, ::wstring, or ::std::wstring object, each NUL
|
||||
// character in it is replaced with "\\0".
|
||||
template <typename T>
|
||||
std::string StreamableToString(const T& streamable) {
|
||||
return (Message() << streamable).GetString();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
@ -0,0 +1,546 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Macros and functions for implementing parameterized tests
|
||||
// in Google C++ Testing and Mocking Framework (Google Test)
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
|
||||
// Value-parameterized tests allow you to test your code with different
|
||||
// parameters without writing multiple copies of the same test.
|
||||
//
|
||||
// Here is how you use value-parameterized tests:
|
||||
|
||||
#if 0
|
||||
|
||||
// To write value-parameterized tests, first you should define a fixture
|
||||
// class. It is usually derived from testing::TestWithParam<T> (see below for
|
||||
// another inheritance scheme that's sometimes useful in more complicated
|
||||
// class hierarchies), where the type of your parameter values.
|
||||
// TestWithParam<T> is itself derived from testing::Test. T can be any
|
||||
// copyable type. If it's a raw pointer, you are responsible for managing the
|
||||
// lifespan of the pointed values.
|
||||
|
||||
class FooTest : public ::testing::TestWithParam<const char*> {
|
||||
// You can implement all the usual class fixture members here.
|
||||
};
|
||||
|
||||
// Then, use the TEST_P macro to define as many parameterized tests
|
||||
// for this fixture as you want. The _P suffix is for "parameterized"
|
||||
// or "pattern", whichever you prefer to think.
|
||||
|
||||
TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, access the test parameter with the GetParam() method
|
||||
// of the TestWithParam<T> class:
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
...
|
||||
}
|
||||
|
||||
TEST_P(FooTest, HasBlahBlah) {
|
||||
...
|
||||
}
|
||||
|
||||
// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test
|
||||
// case with any set of parameters you want. Google Test defines a number
|
||||
// of functions for generating test parameters. They return what we call
|
||||
// (surprise!) parameter generators. Here is a summary of them, which
|
||||
// are all in the testing namespace:
|
||||
//
|
||||
//
|
||||
// Range(begin, end [, step]) - Yields values {begin, begin+step,
|
||||
// begin+step+step, ...}. The values do not
|
||||
// include end. step defaults to 1.
|
||||
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
|
||||
// ValuesIn(container) - Yields values from a C-style array, an STL
|
||||
// ValuesIn(begin,end) container, or an iterator range [begin, end).
|
||||
// Bool() - Yields sequence {false, true}.
|
||||
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
|
||||
// for the math savvy) of the values generated
|
||||
// by the N generators.
|
||||
//
|
||||
// For more details, see comments at the definitions of these functions below
|
||||
// in this file.
|
||||
//
|
||||
// The following statement will instantiate tests from the FooTest test suite
|
||||
// each with parameter values "meeny", "miny", and "moe".
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(InstantiationName,
|
||||
FooTest,
|
||||
Values("meeny", "miny", "moe"));
|
||||
|
||||
// To distinguish different instances of the pattern, (yes, you
|
||||
// can instantiate it more than once) the first argument to the
|
||||
// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the
|
||||
// actual test suite name. Remember to pick unique prefixes for different
|
||||
// instantiations. The tests from the instantiation above will have
|
||||
// these names:
|
||||
//
|
||||
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
|
||||
//
|
||||
// You can use these names in --gtest_filter.
|
||||
//
|
||||
// This statement will instantiate all tests from FooTest again, each
|
||||
// with parameter values "cat" and "dog":
|
||||
|
||||
const char* pets[] = {"cat", "dog"};
|
||||
INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
||||
|
||||
// The tests from the instantiation above will have these names:
|
||||
//
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
|
||||
//
|
||||
// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests
|
||||
// in the given test suite, whether their definitions come before or
|
||||
// AFTER the INSTANTIATE_TEST_SUITE_P statement.
|
||||
//
|
||||
// Please also note that generator expressions (including parameters to the
|
||||
// generators) are evaluated in InitGoogleTest(), after main() has started.
|
||||
// This allows the user on one hand, to adjust generator parameters in order
|
||||
// to dynamically determine a set of tests to run and on the other hand,
|
||||
// give the user a chance to inspect the generated tests with Google Test
|
||||
// reflection API before RUN_ALL_TESTS() is executed.
|
||||
//
|
||||
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
|
||||
// for more examples.
|
||||
//
|
||||
// In the future, we plan to publish the API for defining new parameter
|
||||
// generators. But for now this interface remains part of the internal
|
||||
// implementation and is subject to change.
|
||||
//
|
||||
//
|
||||
// A parameterized test fixture must be derived from testing::Test and from
|
||||
// testing::WithParamInterface<T>, where T is the type of the parameter
|
||||
// values. Inheriting from TestWithParam<T> satisfies that requirement because
|
||||
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
|
||||
// complicated hierarchies, however, it is occasionally useful to inherit
|
||||
// separately from Test and WithParamInterface. For example:
|
||||
|
||||
class BaseTest : public ::testing::Test {
|
||||
// You can inherit all the usual members for a non-parameterized test
|
||||
// fixture here.
|
||||
};
|
||||
|
||||
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
|
||||
// The usual test fixture members go here too.
|
||||
};
|
||||
|
||||
TEST_F(BaseTest, HasFoo) {
|
||||
// This is an ordinary non-parameterized test.
|
||||
}
|
||||
|
||||
TEST_P(DerivedTest, DoesBlah) {
|
||||
// GetParam works just the same here as if you inherit from TestWithParam.
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-param-util.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Functions producing parameter generators.
|
||||
//
|
||||
// Google Test uses these generators to produce parameters for value-
|
||||
// parameterized tests. When a parameterized test suite is instantiated
|
||||
// with a particular generator, Google Test creates and runs tests
|
||||
// for each element in the sequence produced by the generator.
|
||||
//
|
||||
// In the following sample, tests from test suite FooTest are instantiated
|
||||
// each three times with parameter values 3, 5, and 8:
|
||||
//
|
||||
// class FooTest : public TestWithParam<int> { ... };
|
||||
//
|
||||
// TEST_P(FooTest, TestThis) {
|
||||
// }
|
||||
// TEST_P(FooTest, TestThat) {
|
||||
// }
|
||||
// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8));
|
||||
//
|
||||
|
||||
// Range() returns generators providing sequences of values in a range.
|
||||
//
|
||||
// Synopsis:
|
||||
// Range(start, end)
|
||||
// - returns a generator producing a sequence of values {start, start+1,
|
||||
// start+2, ..., }.
|
||||
// Range(start, end, step)
|
||||
// - returns a generator producing a sequence of values {start, start+step,
|
||||
// start+step+step, ..., }.
|
||||
// Notes:
|
||||
// * The generated sequences never include end. For example, Range(1, 5)
|
||||
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
|
||||
// returns a generator producing {1, 3, 5, 7}.
|
||||
// * start and end must have the same type. That type may be any integral or
|
||||
// floating-point type or a user defined type satisfying these conditions:
|
||||
// * It must be assignable (have operator=() defined).
|
||||
// * It must have operator+() (operator+(int-compatible type) for
|
||||
// two-operand version).
|
||||
// * It must have operator<() defined.
|
||||
// Elements in the resulting sequences will also have that type.
|
||||
// * Condition start < end must be satisfied in order for resulting sequences
|
||||
// to contain any elements.
|
||||
//
|
||||
template <typename T, typename IncrementT>
|
||||
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
|
||||
return internal::ParamGenerator<T>(
|
||||
new internal::RangeGenerator<T, IncrementT>(start, end, step));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
internal::ParamGenerator<T> Range(T start, T end) {
|
||||
return Range(start, end, 1);
|
||||
}
|
||||
|
||||
// ValuesIn() function allows generation of tests with parameters coming from
|
||||
// a container.
|
||||
//
|
||||
// Synopsis:
|
||||
// ValuesIn(const T (&array)[N])
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a C-style array.
|
||||
// ValuesIn(const Container& container)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// an STL-style container.
|
||||
// ValuesIn(Iterator begin, Iterator end)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a range [begin, end) defined by a pair of STL-style iterators. These
|
||||
// iterators can also be plain C pointers.
|
||||
//
|
||||
// Please note that ValuesIn copies the values from the containers
|
||||
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// This instantiates tests from test suite StringTest
|
||||
// each with C-string values of "foo", "bar", and "baz":
|
||||
//
|
||||
// const char* strings[] = {"foo", "bar", "baz"};
|
||||
// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));
|
||||
//
|
||||
// This instantiates tests from test suite StlStringTest
|
||||
// each with STL strings with values "a" and "b":
|
||||
//
|
||||
// ::std::vector< ::std::string> GetParameterStrings() {
|
||||
// ::std::vector< ::std::string> v;
|
||||
// v.push_back("a");
|
||||
// v.push_back("b");
|
||||
// return v;
|
||||
// }
|
||||
//
|
||||
// INSTANTIATE_TEST_SUITE_P(CharSequence,
|
||||
// StlStringTest,
|
||||
// ValuesIn(GetParameterStrings()));
|
||||
//
|
||||
//
|
||||
// This will also instantiate tests from CharTest
|
||||
// each with parameter values 'a' and 'b':
|
||||
//
|
||||
// ::std::list<char> GetParameterChars() {
|
||||
// ::std::list<char> list;
|
||||
// list.push_back('a');
|
||||
// list.push_back('b');
|
||||
// return list;
|
||||
// }
|
||||
// ::std::list<char> l = GetParameterChars();
|
||||
// INSTANTIATE_TEST_SUITE_P(CharSequence2,
|
||||
// CharTest,
|
||||
// ValuesIn(l.begin(), l.end()));
|
||||
//
|
||||
template <typename ForwardIterator>
|
||||
internal::ParamGenerator<
|
||||
typename std::iterator_traits<ForwardIterator>::value_type>
|
||||
ValuesIn(ForwardIterator begin, ForwardIterator end) {
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type ParamType;
|
||||
return internal::ParamGenerator<ParamType>(
|
||||
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
|
||||
return ValuesIn(array, array + N);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
const Container& container) {
|
||||
return ValuesIn(container.begin(), container.end());
|
||||
}
|
||||
|
||||
// Values() allows generating tests from explicitly specified list of
|
||||
// parameters.
|
||||
//
|
||||
// Synopsis:
|
||||
// Values(T v1, T v2, ..., T vN)
|
||||
// - returns a generator producing sequences with elements v1, v2, ..., vN.
|
||||
//
|
||||
// For example, this instantiates tests from test suite BarTest each
|
||||
// with values "one", "two", and "three":
|
||||
//
|
||||
// INSTANTIATE_TEST_SUITE_P(NumSequence,
|
||||
// BarTest,
|
||||
// Values("one", "two", "three"));
|
||||
//
|
||||
// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.
|
||||
// The exact type of values will depend on the type of parameter in BazTest.
|
||||
//
|
||||
// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
|
||||
//
|
||||
//
|
||||
template <typename... T>
|
||||
internal::ValueArray<T...> Values(T... v) {
|
||||
return internal::ValueArray<T...>(std::move(v)...);
|
||||
}
|
||||
|
||||
// Bool() allows generating tests with parameters in a set of (false, true).
|
||||
//
|
||||
// Synopsis:
|
||||
// Bool()
|
||||
// - returns a generator producing sequences with elements {false, true}.
|
||||
//
|
||||
// It is useful when testing code that depends on Boolean flags. Combinations
|
||||
// of multiple flags can be tested when several Bool()'s are combined using
|
||||
// Combine() function.
|
||||
//
|
||||
// In the following example all tests in the test suite FlagDependentTest
|
||||
// will be instantiated twice with parameters false and true.
|
||||
//
|
||||
// class FlagDependentTest : public testing::TestWithParam<bool> {
|
||||
// virtual void SetUp() {
|
||||
// external_flag = GetParam();
|
||||
// }
|
||||
// }
|
||||
// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
|
||||
//
|
||||
inline internal::ParamGenerator<bool> Bool() { return Values(false, true); }
|
||||
|
||||
// Combine() allows the user to combine two or more sequences to produce
|
||||
// values of a Cartesian product of those sequences' elements.
|
||||
//
|
||||
// Synopsis:
|
||||
// Combine(gen1, gen2, ..., genN)
|
||||
// - returns a generator producing sequences with elements coming from
|
||||
// the Cartesian product of elements from the sequences generated by
|
||||
// gen1, gen2, ..., genN. The sequence elements will have a type of
|
||||
// std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
|
||||
// of elements from sequences produces by gen1, gen2, ..., genN.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This will instantiate tests in test suite AnimalTest each one with
|
||||
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||
//
|
||||
// enum Color { BLACK, GRAY, WHITE };
|
||||
// class AnimalTest
|
||||
// : public testing::TestWithParam<std::tuple<const char*, Color> > {...};
|
||||
//
|
||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||
//
|
||||
// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE)));
|
||||
//
|
||||
// This will instantiate tests in FlagDependentTest with all variations of two
|
||||
// Boolean flags:
|
||||
//
|
||||
// class FlagDependentTest
|
||||
// : public testing::TestWithParam<std::tuple<bool, bool> > {
|
||||
// virtual void SetUp() {
|
||||
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
|
||||
// std::tie(external_flag_1, external_flag_2) = GetParam();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// TEST_P(FlagDependentTest, TestFeature1) {
|
||||
// // Test your code using external_flag_1 and external_flag_2 here.
|
||||
// }
|
||||
// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest,
|
||||
// Combine(Bool(), Bool()));
|
||||
//
|
||||
template <typename... Generator>
|
||||
internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
|
||||
return internal::CartesianProductHolder<Generator...>(g...);
|
||||
}
|
||||
|
||||
// ConvertGenerator() wraps a parameter generator in order to cast each produced
|
||||
// value through a known type before supplying it to the test suite
|
||||
//
|
||||
// Synopsis:
|
||||
// ConvertGenerator<T>(gen)
|
||||
// - returns a generator producing the same elements as generated by gen, but
|
||||
// each element is static_cast to type T before being returned
|
||||
//
|
||||
// It is useful when using the Combine() function to get the generated
|
||||
// parameters in a custom type instead of std::tuple
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This will instantiate tests in test suite AnimalTest each one with
|
||||
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||
//
|
||||
// enum Color { BLACK, GRAY, WHITE };
|
||||
// struct ParamType {
|
||||
// using TupleT = std::tuple<const char*, Color>;
|
||||
// std::string animal;
|
||||
// Color color;
|
||||
// ParamType(TupleT t) : animal(std::get<0>(t)), color(std::get<1>(t)) {}
|
||||
// };
|
||||
// class AnimalTest
|
||||
// : public testing::TestWithParam<ParamType> {...};
|
||||
//
|
||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||
//
|
||||
// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
|
||||
// ConvertGenerator<ParamType::TupleT>(
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE))));
|
||||
//
|
||||
template <typename T>
|
||||
internal::ParamConverterGenerator<T> ConvertGenerator(
|
||||
internal::ParamGenerator<T> gen) {
|
||||
return internal::ParamConverterGenerator<T>(gen);
|
||||
}
|
||||
|
||||
#define TEST_P(test_suite_name, test_name) \
|
||||
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
|
||||
: public test_suite_name, \
|
||||
private ::testing::internal::GTestNonCopyable { \
|
||||
public: \
|
||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
||||
void TestBody() override; \
|
||||
\
|
||||
private: \
|
||||
static int AddToRegistry() { \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||
GTEST_STRINGIFY_(test_suite_name), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||
->AddTestPattern( \
|
||||
GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \
|
||||
new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \
|
||||
test_suite_name, test_name)>(), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||
}; \
|
||||
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
|
||||
test_name)::gtest_registering_dummy_ = \
|
||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \
|
||||
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
|
||||
|
||||
// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify
|
||||
// generator and an optional function or functor that generates custom test name
|
||||
// suffixes based on the test parameters. Such a function or functor should
|
||||
// accept one argument of type testing::TestParamInfo<class ParamType>, and
|
||||
// return std::string.
|
||||
//
|
||||
// testing::PrintToStringParamName is a builtin test suffix generator that
|
||||
// returns the value of testing::PrintToString(GetParam()).
|
||||
//
|
||||
// Note: test names must be non-empty, unique, and may only contain ASCII
|
||||
// alphanumeric characters or underscore. Because PrintToString adds quotes
|
||||
// to std::string and C strings, it won't work for these types.
|
||||
|
||||
#define GTEST_EXPAND_(arg) arg
|
||||
#define GTEST_GET_FIRST_(first, ...) first
|
||||
#define GTEST_GET_SECOND_(first, second, ...) second
|
||||
|
||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||
} \
|
||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
|
||||
if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))); \
|
||||
auto t = std::make_tuple(__VA_ARGS__); \
|
||||
static_assert(std::tuple_size<decltype(t)>::value <= 2, \
|
||||
"Too Many Args!"); \
|
||||
} \
|
||||
return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
DUMMY_PARAM_))))(info); \
|
||||
} \
|
||||
static int gtest_##prefix##test_suite_name##_dummy_ \
|
||||
GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
.GetTestSuitePatternHolder<test_suite_name>( \
|
||||
GTEST_STRINGIFY_(test_suite_name), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
|
||||
->AddTestSuiteInstantiation( \
|
||||
GTEST_STRINGIFY_(prefix), \
|
||||
>est_##prefix##test_suite_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_suite_name##_EvalGenerateName_, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
// Allow Marking a Parameterized test class as not needing to be instantiated.
|
||||
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
|
||||
namespace gtest_do_not_use_outside_namespace_scope {} \
|
||||
static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \
|
||||
GTEST_STRINGIFY_(T))
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
#define INSTANTIATE_TEST_CASE_P \
|
||||
static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \
|
||||
""); \
|
||||
INSTANTIATE_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,250 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Utilities for testing Google Test itself and code that uses Google Test
|
||||
// (e.g. frameworks built on top of Google Test).
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This helper class can be used to mock out Google Test failure reporting
|
||||
// so that we can test Google Test or code that builds on Google Test.
|
||||
//
|
||||
// An object of this class appends a TestPartResult object to the
|
||||
// TestPartResultArray object given in the constructor whenever a Google Test
|
||||
// failure is reported. It can either intercept only failures that are
|
||||
// generated in the same thread that created this object or it can intercept
|
||||
// all generated failures. The scope of this mock object can be controlled with
|
||||
// the second argument to the two arguments constructor.
|
||||
class GTEST_API_ ScopedFakeTestPartResultReporter
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
// The two possible mocking modes of this object.
|
||||
enum InterceptMode {
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
|
||||
INTERCEPT_ALL_THREADS // Intercepts all failures.
|
||||
};
|
||||
|
||||
// The c'tor sets this object as the test part result reporter used
|
||||
// by Google Test. The 'result' parameter specifies where to report the
|
||||
// results. This reporter will only catch failures generated in the current
|
||||
// thread. DEPRECATED
|
||||
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
|
||||
|
||||
// Same as above, but you can choose the interception scope of this object.
|
||||
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
|
||||
TestPartResultArray* result);
|
||||
|
||||
// The d'tor restores the previous test part result reporter.
|
||||
~ScopedFakeTestPartResultReporter() override;
|
||||
|
||||
// Appends the TestPartResult object to the TestPartResultArray
|
||||
// received in the constructor.
|
||||
//
|
||||
// This method is from the TestPartResultReporterInterface
|
||||
// interface.
|
||||
void ReportTestPartResult(const TestPartResult& result) override;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
const InterceptMode intercept_mode_;
|
||||
TestPartResultReporterInterface* old_reporter_;
|
||||
TestPartResultArray* const result_;
|
||||
|
||||
ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) =
|
||||
delete;
|
||||
ScopedFakeTestPartResultReporter& operator=(
|
||||
const ScopedFakeTestPartResultReporter&) = delete;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// A helper class for implementing EXPECT_FATAL_FAILURE() and
|
||||
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
|
||||
// TestPartResultArray contains exactly one failure that has the given
|
||||
// type and contains the given substring. If that's not the case, a
|
||||
// non-fatal failure will be generated.
|
||||
class GTEST_API_ SingleFailureChecker {
|
||||
public:
|
||||
// The constructor remembers the arguments.
|
||||
SingleFailureChecker(const TestPartResultArray* results,
|
||||
TestPartResult::Type type, const std::string& substr);
|
||||
~SingleFailureChecker();
|
||||
|
||||
private:
|
||||
const TestPartResultArray* const results_;
|
||||
const TestPartResult::Type type_;
|
||||
const std::string substr_;
|
||||
|
||||
SingleFailureChecker(const SingleFailureChecker&) = delete;
|
||||
SingleFailureChecker& operator=(const SingleFailureChecker&) = delete;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
// A set of macros for testing Google Test assertions or code that's expected
|
||||
// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but
|
||||
// not a non-fatal failure, as from EXPECT_EQ). It verifies that the given
|
||||
// statement will cause exactly one fatal Google Test failure with 'substr'
|
||||
// being part of the failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - 'statement' cannot reference local non-static variables or
|
||||
// non-static members of the current object.
|
||||
// - 'statement' cannot return a value.
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
||||
// gtest_unittest.cc will fail to compile if we do that.
|
||||
#define EXPECT_FATAL_FAILURE(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper { \
|
||||
public: \
|
||||
static void Execute() { statement; } \
|
||||
}; \
|
||||
::testing::TestPartResultArray gtest_failures; \
|
||||
::testing::internal::SingleFailureChecker gtest_checker( \
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
|
||||
{ \
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, \
|
||||
>est_failures); \
|
||||
GTestExpectFatalFailureHelper::Execute(); \
|
||||
} \
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper { \
|
||||
public: \
|
||||
static void Execute() { statement; } \
|
||||
}; \
|
||||
::testing::TestPartResultArray gtest_failures; \
|
||||
::testing::internal::SingleFailureChecker gtest_checker( \
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
|
||||
{ \
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
||||
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
||||
>est_failures); \
|
||||
GTestExpectFatalFailureHelper::Execute(); \
|
||||
} \
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
// A macro for testing Google Test assertions or code that's expected to
|
||||
// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ,
|
||||
// but not from an ASSERT_EQ). It asserts that the given statement will cause
|
||||
// exactly one non-fatal Google Test failure with 'substr' being part of the
|
||||
// failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// 'statement' is allowed to reference local variables and members of
|
||||
// the current object.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. If we do that, the code won't compile when the user gives
|
||||
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
||||
// expands to code containing an unprotected comma. The
|
||||
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
||||
// catches that.
|
||||
//
|
||||
// For the same reason, we have to write
|
||||
// if (::testing::internal::AlwaysTrue()) { statement; }
|
||||
// instead of
|
||||
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
// to avoid an MSVC warning on unreachable code.
|
||||
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
|
||||
do { \
|
||||
::testing::TestPartResultArray gtest_failures; \
|
||||
::testing::internal::SingleFailureChecker gtest_checker( \
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr)); \
|
||||
{ \
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, \
|
||||
>est_failures); \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
statement; \
|
||||
} \
|
||||
} \
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do { \
|
||||
::testing::TestPartResultArray gtest_failures; \
|
||||
::testing::internal::SingleFailureChecker gtest_checker( \
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr)); \
|
||||
{ \
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
|
||||
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
||||
>est_failures); \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
statement; \
|
||||
} \
|
||||
} \
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
@ -0,0 +1,192 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
// A copyable object representing the result of a test part (i.e. an
|
||||
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||
//
|
||||
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||
class GTEST_API_ TestPartResult {
|
||||
public:
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
enum Type {
|
||||
kSuccess, // Succeeded.
|
||||
kNonFatalFailure, // Failed but the test can continue.
|
||||
kFatalFailure, // Failed and the test should be terminated.
|
||||
kSkip // Skipped.
|
||||
};
|
||||
|
||||
// C'tor. TestPartResult does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
// TestPartResult object.
|
||||
TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
|
||||
const char* a_message)
|
||||
: type_(a_type),
|
||||
file_name_(a_file_name == nullptr ? "" : a_file_name),
|
||||
line_number_(a_line_number),
|
||||
summary_(ExtractSummary(a_message)),
|
||||
message_(a_message) {}
|
||||
|
||||
// Gets the outcome of the test part.
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Gets the name of the source file where the test part took place, or
|
||||
// NULL if it's unknown.
|
||||
const char* file_name() const {
|
||||
return file_name_.empty() ? nullptr : file_name_.c_str();
|
||||
}
|
||||
|
||||
// Gets the line in the source file where the test part took place,
|
||||
// or -1 if it's unknown.
|
||||
int line_number() const { return line_number_; }
|
||||
|
||||
// Gets the summary of the failure message.
|
||||
const char* summary() const { return summary_.c_str(); }
|
||||
|
||||
// Gets the message associated with the test part.
|
||||
const char* message() const { return message_.c_str(); }
|
||||
|
||||
// Returns true if and only if the test part was skipped.
|
||||
bool skipped() const { return type_ == kSkip; }
|
||||
|
||||
// Returns true if and only if the test part passed.
|
||||
bool passed() const { return type_ == kSuccess; }
|
||||
|
||||
// Returns true if and only if the test part non-fatally failed.
|
||||
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
||||
|
||||
// Returns true if and only if the test part fatally failed.
|
||||
bool fatally_failed() const { return type_ == kFatalFailure; }
|
||||
|
||||
// Returns true if and only if the test part failed.
|
||||
bool failed() const { return fatally_failed() || nonfatally_failed(); }
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack
|
||||
// trace in it.
|
||||
static std::string ExtractSummary(const char* message);
|
||||
|
||||
// The name of the source file where the test part took place, or
|
||||
// "" if the source file is unknown.
|
||||
std::string file_name_;
|
||||
// The line in the source file where the test part took place, or -1
|
||||
// if the line number is unknown.
|
||||
int line_number_;
|
||||
std::string summary_; // The test failure summary.
|
||||
std::string message_; // The test failure message.
|
||||
};
|
||||
|
||||
// Prints a TestPartResult object.
|
||||
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
||||
|
||||
// An array of TestPartResult objects.
|
||||
//
|
||||
// Don't inherit from TestPartResultArray as its destructor is not
|
||||
// virtual.
|
||||
class GTEST_API_ TestPartResultArray {
|
||||
public:
|
||||
TestPartResultArray() = default;
|
||||
|
||||
// Appends the given TestPartResult to the array.
|
||||
void Append(const TestPartResult& result);
|
||||
|
||||
// Returns the TestPartResult at the given index (0-based).
|
||||
const TestPartResult& GetTestPartResult(int index) const;
|
||||
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int size() const;
|
||||
|
||||
private:
|
||||
std::vector<TestPartResult> array_;
|
||||
|
||||
TestPartResultArray(const TestPartResultArray&) = delete;
|
||||
TestPartResultArray& operator=(const TestPartResultArray&) = delete;
|
||||
};
|
||||
|
||||
// This interface knows how to report a test part result.
|
||||
class GTEST_API_ TestPartResultReporterInterface {
|
||||
public:
|
||||
virtual ~TestPartResultReporterInterface() = default;
|
||||
|
||||
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
|
||||
// statement generates new fatal failures. To do so it registers itself as the
|
||||
// current test part result reporter. Besides checking if fatal failures were
|
||||
// reported, it only delegates the reporting to the former result reporter.
|
||||
// The original result reporter is restored in the destructor.
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
class GTEST_API_ HasNewFatalFailureHelper
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
HasNewFatalFailureHelper();
|
||||
~HasNewFatalFailureHelper() override;
|
||||
void ReportTestPartResult(const TestPartResult& result) override;
|
||||
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
||||
|
||||
private:
|
||||
bool has_new_fatal_failure_;
|
||||
TestPartResultReporterInterface* original_reporter_;
|
||||
|
||||
HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete;
|
||||
HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
@ -0,0 +1,331 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
|
||||
// This header implements typed tests and type-parameterized tests.
|
||||
|
||||
// Typed (aka type-driven) tests repeat the same test for types in a
|
||||
// list. You must know which types you want to test with when writing
|
||||
// typed tests. Here's how you do it:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
public:
|
||||
...
|
||||
typedef std::list<T> List;
|
||||
static T shared_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
// Next, associate a list of types with the test suite, which will be
|
||||
// repeated for each type in the list. The typedef is necessary for
|
||||
// the macro to parse correctly.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
TYPED_TEST_SUITE(FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// TYPED_TEST_SUITE(FooTest, int);
|
||||
|
||||
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||
// tests for this test suite as you want.
|
||||
TYPED_TEST(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to the special name TypeParam to get the type
|
||||
// parameter. Since we are inside a derived class template, C++ requires
|
||||
// us to visit the members of FooTest via 'this'.
|
||||
TypeParam n = this->value_;
|
||||
|
||||
// To visit static members of the fixture, add the TestFixture::
|
||||
// prefix.
|
||||
n += TestFixture::shared_;
|
||||
|
||||
// To refer to typedefs in the fixture, add the "typename
|
||||
// TestFixture::" prefix.
|
||||
typename TestFixture::List values;
|
||||
values.push_back(n);
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST(FooTest, HasPropertyA) { ... }
|
||||
|
||||
// TYPED_TEST_SUITE takes an optional third argument which allows to specify a
|
||||
// class that generates custom test name suffixes based on the type. This should
|
||||
// be a class which has a static template function GetName(int index) returning
|
||||
// a string for each type. The provided integer index equals the index of the
|
||||
// type in the provided type list. In many cases the index can be ignored.
|
||||
//
|
||||
// For example:
|
||||
// class MyTypeNames {
|
||||
// public:
|
||||
// template <typename T>
|
||||
// static std::string GetName(int) {
|
||||
// if (std::is_same<T, char>()) return "char";
|
||||
// if (std::is_same<T, int>()) return "int";
|
||||
// if (std::is_same<T, unsigned int>()) return "unsignedInt";
|
||||
// }
|
||||
// };
|
||||
// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);
|
||||
|
||||
#endif // 0
|
||||
|
||||
// Type-parameterized tests are abstract test patterns parameterized
|
||||
// by a type. Compared with typed tests, type-parameterized tests
|
||||
// allow you to define the test pattern without knowing what the type
|
||||
// parameters are. The defined pattern can be instantiated with
|
||||
// different types any number of times, in any number of translation
|
||||
// units.
|
||||
//
|
||||
// If you are designing an interface or concept, you can define a
|
||||
// suite of type-parameterized tests to verify properties that any
|
||||
// valid implementation of the interface/concept should have. Then,
|
||||
// each implementation can easily instantiate the test suite to verify
|
||||
// that it conforms to the requirements, without having to write
|
||||
// similar tests repeatedly. Here's an example:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
...
|
||||
};
|
||||
|
||||
// Next, declare that you will define a type-parameterized test suite
|
||||
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||
// prefer):
|
||||
TYPED_TEST_SUITE_P(FooTest);
|
||||
|
||||
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||
// for this type-parameterized test suite as you want.
|
||||
TYPED_TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
TypeParam n = 0;
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
|
||||
|
||||
// Now the tricky part: you need to register all test patterns before
|
||||
// you can instantiate them. The first argument of the macro is the
|
||||
// test suite name; the rest are the names of the tests in this test
|
||||
// case.
|
||||
REGISTER_TYPED_TEST_SUITE_P(FooTest,
|
||||
DoesBlah, HasPropertyA);
|
||||
|
||||
// Finally, you are free to instantiate the pattern with the types you
|
||||
// want. If you put the above code in a header file, you can #include
|
||||
// it in multiple C++ source files and instantiate it multiple times.
|
||||
//
|
||||
// To distinguish different instances of the pattern, the first
|
||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||
// to the actual test suite name. Remember to pick unique prefixes for
|
||||
// different instances.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);
|
||||
//
|
||||
// Similar to the optional argument of TYPED_TEST_SUITE above,
|
||||
// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to
|
||||
// generate custom names.
|
||||
// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-type-util.h"
|
||||
|
||||
// Implements typed tests.
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the typedef for the type parameters of the
|
||||
// given test suite.
|
||||
#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_
|
||||
|
||||
// Expands to the name of the typedef for the NameGenerator, responsible for
|
||||
// creating the suffixes of the name.
|
||||
#define GTEST_NAME_GENERATOR_(TestSuiteName) \
|
||||
gtest_type_params_##TestSuiteName##_NameGenerator
|
||||
|
||||
#define TYPED_TEST_SUITE(CaseName, Types, ...) \
|
||||
typedef ::testing::internal::GenerateTypeList<Types>::type \
|
||||
GTEST_TYPE_PARAMS_(CaseName); \
|
||||
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
|
||||
GTEST_NAME_GENERATOR_(CaseName)
|
||||
|
||||
#define TYPED_TEST(CaseName, TestName) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
|
||||
"test-name must not be empty"); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
static bool gtest_##CaseName##_##TestName##_registered_ \
|
||||
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
TestName)>, \
|
||||
GTEST_TYPE_PARAMS_( \
|
||||
CaseName)>::Register("", \
|
||||
::testing::internal::CodeLocation( \
|
||||
__FILE__, __LINE__), \
|
||||
GTEST_STRINGIFY_(CaseName), \
|
||||
GTEST_STRINGIFY_(TestName), 0, \
|
||||
::testing::internal::GenerateNames< \
|
||||
GTEST_NAME_GENERATOR_(CaseName), \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>()); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, \
|
||||
TestName)<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
#define TYPED_TEST_CASE \
|
||||
static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \
|
||||
TYPED_TEST_SUITE
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
// Implements type-parameterized tests.
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the namespace name that the type-parameterized tests for
|
||||
// the given type-parameterized test suite are defined in. The exact
|
||||
// name of the namespace is subject to change without notice.
|
||||
#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the defined tests in the given test suite.
|
||||
#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \
|
||||
gtest_typed_test_suite_p_state_##TestSuiteName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the registered tests in the given test suite.
|
||||
#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \
|
||||
gtest_registered_test_names_##TestSuiteName##_
|
||||
|
||||
// The variables defined in the type-parameterized test macros are
|
||||
// static as typically these macros are used in a .h file that can be
|
||||
// #included in multiple translation units linked together.
|
||||
#define TYPED_TEST_SUITE_P(SuiteName) \
|
||||
static ::testing::internal::TypedTestSuitePState \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
#define TYPED_TEST_CASE_P \
|
||||
static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \
|
||||
TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// Note: this won't work correctly if the trailing arguments are macros.
|
||||
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
|
||||
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
|
||||
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
#define REGISTER_TYPED_TEST_CASE_P \
|
||||
static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \
|
||||
""); \
|
||||
REGISTER_TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
|
||||
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
|
||||
"test-suit-prefix must not be empty"); \
|
||||
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTestSuite< \
|
||||
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>:: \
|
||||
Register(GTEST_STRINGIFY_(Prefix), \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||
>EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
|
||||
GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
|
||||
::testing::internal::GenerateNames< \
|
||||
::testing::internal::NameGeneratorSelector< \
|
||||
__VA_ARGS__>::type, \
|
||||
::testing::internal::GenerateTypeList<Types>::type>())
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
#define INSTANTIATE_TYPED_TEST_CASE_P \
|
||||
static_assert( \
|
||||
::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,279 @@
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Implements a family of generic predicate assertion macros.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
|
||||
#include "gtest/gtest-assertion-result.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This header implements a family of generic predicate assertion
|
||||
// macros:
|
||||
//
|
||||
// ASSERT_PRED_FORMAT1(pred_format, v1)
|
||||
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred_format is a function or functor that takes n (in the
|
||||
// case of ASSERT_PRED_FORMATn) values and their source expression
|
||||
// text, and returns a testing::AssertionResult. See the definition
|
||||
// of ASSERT_EQ in gtest.h for an example.
|
||||
//
|
||||
// If you don't care about formatting, you can use the more
|
||||
// restrictive version:
|
||||
//
|
||||
// ASSERT_PRED1(pred, v1)
|
||||
// ASSERT_PRED2(pred, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred is an n-ary function or functor that returns bool,
|
||||
// and the values v1, v2, ..., must support the << operator for
|
||||
// streaming to std::ostream.
|
||||
//
|
||||
// We also define the EXPECT_* variations.
|
||||
//
|
||||
// For now we only support predicates whose arity is at most 5.
|
||||
// Please email googletestframework@googlegroups.com if you need
|
||||
// support for higher arities.
|
||||
|
||||
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||
// in this file reduce. Don't use this in your code.
|
||||
|
||||
#define GTEST_ASSERT_(expression, on_failure) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const ::testing::AssertionResult gtest_ar = (expression)) \
|
||||
; \
|
||||
else \
|
||||
on_failure(gtest_ar.failure_message())
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred, typename T1>
|
||||
AssertionResult AssertPred1Helper(const char* pred_text, const char* e1,
|
||||
Pred pred, const T1& v1) {
|
||||
if (pred(v1)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure()
|
||||
<< pred_text << "(" << e1 << ") evaluates to false, where"
|
||||
<< "\n"
|
||||
<< e1 << " evaluates to " << ::testing::PrintToString(v1);
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \
|
||||
GTEST_ASSERT_(pred_format(#v1, v1), on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED1_(pred, v1, on_failure) \
|
||||
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure)
|
||||
|
||||
// Unary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred, typename T1, typename T2>
|
||||
AssertionResult AssertPred2Helper(const char* pred_text, const char* e1,
|
||||
const char* e2, Pred pred, const T1& v1,
|
||||
const T2& v2) {
|
||||
if (pred(v1, v2)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure()
|
||||
<< pred_text << "(" << e1 << ", " << e2
|
||||
<< ") evaluates to false, where"
|
||||
<< "\n"
|
||||
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||
<< e2 << " evaluates to " << ::testing::PrintToString(v2);
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED2_(pred, v1, v2, on_failure) \
|
||||
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \
|
||||
on_failure)
|
||||
|
||||
// Binary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred, typename T1, typename T2, typename T3>
|
||||
AssertionResult AssertPred3Helper(const char* pred_text, const char* e1,
|
||||
const char* e2, const char* e3, Pred pred,
|
||||
const T1& v1, const T2& v2, const T3& v3) {
|
||||
if (pred(v1, v2, v3)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure()
|
||||
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3
|
||||
<< ") evaluates to false, where"
|
||||
<< "\n"
|
||||
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||
<< e3 << " evaluates to " << ::testing::PrintToString(v3);
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \
|
||||
GTEST_ASSERT_( \
|
||||
::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \
|
||||
on_failure)
|
||||
|
||||
// Ternary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred, typename T1, typename T2, typename T3, typename T4>
|
||||
AssertionResult AssertPred4Helper(const char* pred_text, const char* e1,
|
||||
const char* e2, const char* e3,
|
||||
const char* e4, Pred pred, const T1& v1,
|
||||
const T2& v2, const T3& v3, const T4& v4) {
|
||||
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure()
|
||||
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
||||
<< ") evaluates to false, where"
|
||||
<< "\n"
|
||||
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||
<< e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
||||
<< e4 << " evaluates to " << ::testing::PrintToString(v4);
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \
|
||||
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \
|
||||
v1, v2, v3, v4), \
|
||||
on_failure)
|
||||
|
||||
// 4-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred, typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5>
|
||||
AssertionResult AssertPred5Helper(const char* pred_text, const char* e1,
|
||||
const char* e2, const char* e3,
|
||||
const char* e4, const char* e5, Pred pred,
|
||||
const T1& v1, const T2& v2, const T3& v3,
|
||||
const T4& v4, const T5& v5) {
|
||||
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure()
|
||||
<< pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
|
||||
<< ", " << e5 << ") evaluates to false, where"
|
||||
<< "\n"
|
||||
<< e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
|
||||
<< e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
|
||||
<< e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
|
||||
<< e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n"
|
||||
<< e5 << " evaluates to " << ::testing::PrintToString(v5);
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure) \
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \
|
||||
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \
|
||||
pred, v1, v2, v3, v4, v5), \
|
||||
on_failure)
|
||||
|
||||
// 5-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
@ -0,0 +1,60 @@
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google C++ Testing and Mocking Framework definitions useful in production
|
||||
// code.
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
|
||||
// When you need to test the private or protected members of a class,
|
||||
// use the FRIEND_TEST macro to declare your tests as friends of the
|
||||
// class. For example:
|
||||
//
|
||||
// class MyClass {
|
||||
// private:
|
||||
// void PrivateMethod();
|
||||
// FRIEND_TEST(MyClassTest, PrivateMethodWorks);
|
||||
// };
|
||||
//
|
||||
// class MyClassTest : public testing::Test {
|
||||
// // ...
|
||||
// };
|
||||
//
|
||||
// TEST_F(MyClassTest, PrivateMethodWorks) {
|
||||
// // Can call MyClass::PrivateMethod() here.
|
||||
// }
|
||||
//
|
||||
// Note: The test class must be in the same namespace as the class being tested.
|
||||
// For example, putting MyClassTest in an anonymous namespace will not work.
|
||||
|
||||
#define FRIEND_TEST(test_case_name, test_name) \
|
||||
friend class test_case_name##_##test_name##_Test
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
@ -0,0 +1,44 @@
|
||||
# Customization Points
|
||||
|
||||
The custom directory is an injection point for custom user configurations.
|
||||
|
||||
## Header `gtest.h`
|
||||
|
||||
### The following macros can be defined:
|
||||
|
||||
* `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of
|
||||
`OsStackTraceGetterInterface`.
|
||||
* `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See
|
||||
`testing::TempDir` for semantics and signature.
|
||||
|
||||
## Header `gtest-port.h`
|
||||
|
||||
The following macros can be defined:
|
||||
|
||||
### Logging:
|
||||
|
||||
* `GTEST_LOG_(severity)`
|
||||
* `GTEST_CHECK_(condition)`
|
||||
* Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too.
|
||||
|
||||
### Threading:
|
||||
|
||||
* `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided.
|
||||
* `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal`
|
||||
are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)`
|
||||
and `GTEST_DEFINE_STATIC_MUTEX_(mutex)`
|
||||
* `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)`
|
||||
* `GTEST_LOCK_EXCLUDED_(locks)`
|
||||
|
||||
### Underlying library support features
|
||||
|
||||
* `GTEST_HAS_CXXABI_H_`
|
||||
|
||||
### Exporting API symbols:
|
||||
|
||||
* `GTEST_API_` - Specifier for exported symbols.
|
||||
|
||||
## Header `gtest-printers.h`
|
||||
|
||||
* See documentation at `gtest/gtest-printers.h` for details on how to define a
|
||||
custom printer.
|
||||
@ -0,0 +1,37 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Injection point for custom user configurations. See README for details
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||
@ -0,0 +1,42 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This file provides an injection point for custom printers in a local
|
||||
// installation of gTest.
|
||||
// It will be included from gtest-printers.h and the overrides in this file
|
||||
// will be visible to everyone.
|
||||
//
|
||||
// Injection point for custom user configurations. See README for details
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||
@ -0,0 +1,37 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Injection point for custom user configurations. See README for details
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||
@ -0,0 +1,307 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// This header file defines internal utilities needed for implementing
|
||||
// death tests. They are subject to change without notice.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest-matchers.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
|
||||
GTEST_DECLARE_string_(internal_run_death_test);
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Names of the flags (needed for parsing Google Test flags).
|
||||
const char kDeathTestStyleFlag[] = "death_test_style";
|
||||
const char kDeathTestUseFork[] = "death_test_use_fork";
|
||||
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
// DeathTest is a class that hides much of the complexity of the
|
||||
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
|
||||
// returns a concrete class that depends on the prevailing death test
|
||||
// style, as defined by the --gtest_death_test_style and/or
|
||||
// --gtest_internal_run_death_test flags.
|
||||
|
||||
// In describing the results of death tests, these terms are used with
|
||||
// the corresponding definitions:
|
||||
//
|
||||
// exit status: The integer exit information in the format specified
|
||||
// by wait(2)
|
||||
// exit code: The integer code passed to exit(3), _exit(2), or
|
||||
// returned from main()
|
||||
class GTEST_API_ DeathTest {
|
||||
public:
|
||||
// Create returns false if there was an error determining the
|
||||
// appropriate action to take for the current death test; for example,
|
||||
// if the gtest_death_test_style flag is set to an invalid value.
|
||||
// The LastMessage method will return a more detailed message in that
|
||||
// case. Otherwise, the DeathTest pointer pointed to by the "test"
|
||||
// argument is set. If the death test should be skipped, the pointer
|
||||
// is set to NULL; otherwise, it is set to the address of a new concrete
|
||||
// DeathTest object that controls the execution of the current test.
|
||||
static bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||
const char* file, int line, DeathTest** test);
|
||||
DeathTest();
|
||||
virtual ~DeathTest() = default;
|
||||
|
||||
// A helper class that aborts a death test when it's deleted.
|
||||
class ReturnSentinel {
|
||||
public:
|
||||
explicit ReturnSentinel(DeathTest* test) : test_(test) {}
|
||||
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
|
||||
|
||||
private:
|
||||
DeathTest* const test_;
|
||||
ReturnSentinel(const ReturnSentinel&) = delete;
|
||||
ReturnSentinel& operator=(const ReturnSentinel&) = delete;
|
||||
};
|
||||
|
||||
// An enumeration of possible roles that may be taken when a death
|
||||
// test is encountered. EXECUTE means that the death test logic should
|
||||
// be executed immediately. OVERSEE means that the program should prepare
|
||||
// the appropriate environment for a child process to execute the death
|
||||
// test, then wait for it to complete.
|
||||
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
|
||||
|
||||
// An enumeration of the three reasons that a test might be aborted.
|
||||
enum AbortReason {
|
||||
TEST_ENCOUNTERED_RETURN_STATEMENT,
|
||||
TEST_THREW_EXCEPTION,
|
||||
TEST_DID_NOT_DIE
|
||||
};
|
||||
|
||||
// Assumes one of the above roles.
|
||||
virtual TestRole AssumeRole() = 0;
|
||||
|
||||
// Waits for the death test to finish and returns its status.
|
||||
virtual int Wait() = 0;
|
||||
|
||||
// Returns true if the death test passed; that is, the test process
|
||||
// exited during the test, its exit status matches a user-supplied
|
||||
// predicate, and its stderr output matches a user-supplied regular
|
||||
// expression.
|
||||
// The user-supplied predicate may be a macro expression rather
|
||||
// than a function pointer or functor, or else Wait and Passed could
|
||||
// be combined.
|
||||
virtual bool Passed(bool exit_status_ok) = 0;
|
||||
|
||||
// Signals that the death test did not die as expected.
|
||||
virtual void Abort(AbortReason reason) = 0;
|
||||
|
||||
// Returns a human-readable outcome message regarding the outcome of
|
||||
// the last death test.
|
||||
static const char* LastMessage();
|
||||
|
||||
static void set_last_death_test_message(const std::string& message);
|
||||
|
||||
private:
|
||||
// A string containing a description of the outcome of the last death test.
|
||||
static std::string last_death_test_message_;
|
||||
|
||||
DeathTest(const DeathTest&) = delete;
|
||||
DeathTest& operator=(const DeathTest&) = delete;
|
||||
};
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
// Factory interface for death tests. May be mocked out for testing.
|
||||
class DeathTestFactory {
|
||||
public:
|
||||
virtual ~DeathTestFactory() = default;
|
||||
virtual bool Create(const char* statement,
|
||||
Matcher<const std::string&> matcher, const char* file,
|
||||
int line, DeathTest** test) = 0;
|
||||
};
|
||||
|
||||
// A concrete DeathTestFactory implementation for normal use.
|
||||
class DefaultDeathTestFactory : public DeathTestFactory {
|
||||
public:
|
||||
bool Create(const char* statement, Matcher<const std::string&> matcher,
|
||||
const char* file, int line, DeathTest** test) override;
|
||||
};
|
||||
|
||||
// Returns true if exit_status describes a process that was terminated
|
||||
// by a signal, or exited normally with a nonzero exit code.
|
||||
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
|
||||
|
||||
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
|
||||
// and interpreted as a regex (rather than an Eq matcher) for legacy
|
||||
// compatibility.
|
||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||
::testing::internal::RE regex) {
|
||||
return ContainsRegex(regex.pattern());
|
||||
}
|
||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
|
||||
return ContainsRegex(regex);
|
||||
}
|
||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||
const ::std::string& regex) {
|
||||
return ContainsRegex(regex);
|
||||
}
|
||||
|
||||
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
|
||||
// used directly.
|
||||
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
|
||||
Matcher<const ::std::string&> matcher) {
|
||||
return matcher;
|
||||
}
|
||||
|
||||
// Traps C++ exceptions escaping statement and reports them as test
|
||||
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||
try { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} catch (const ::std::exception& gtest_exception) { \
|
||||
fprintf( \
|
||||
stderr, \
|
||||
"\n%s: Caught std::exception-derived exception escaping the " \
|
||||
"death test statement. Exception message: %s\n", \
|
||||
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
|
||||
gtest_exception.what()); \
|
||||
fflush(stderr); \
|
||||
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||
} catch (...) { \
|
||||
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
|
||||
}
|
||||
|
||||
#else
|
||||
#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
|
||||
#endif
|
||||
|
||||
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
||||
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
||||
#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
::testing::internal::DeathTest* gtest_dt; \
|
||||
if (!::testing::internal::DeathTest::Create( \
|
||||
#statement, \
|
||||
::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \
|
||||
__FILE__, __LINE__, >est_dt)) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||
} \
|
||||
if (gtest_dt != nullptr) { \
|
||||
std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
|
||||
switch (gtest_dt->AssumeRole()) { \
|
||||
case ::testing::internal::DeathTest::OVERSEE_TEST: \
|
||||
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
|
||||
} \
|
||||
break; \
|
||||
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
||||
const ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
|
||||
gtest_dt); \
|
||||
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
|
||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} else \
|
||||
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \
|
||||
: fail(::testing::internal::DeathTest::LastMessage())
|
||||
// The symbol "fail" here expands to something into which a message
|
||||
// can be streamed.
|
||||
|
||||
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
|
||||
// NDEBUG mode. In this case we need the statements to be executed and the macro
|
||||
// must accept a streamed message even though the message is never printed.
|
||||
// The regex object is not evaluated, but it is used to prevent "unused"
|
||||
// warnings and to avoid an expression that doesn't compile in debug mode.
|
||||
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} else if (!::testing::internal::AlwaysTrue()) { \
|
||||
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
// A class representing the parsed contents of the
|
||||
// --gtest_internal_run_death_test flag, as it existed when
|
||||
// RUN_ALL_TESTS was called.
|
||||
class InternalRunDeathTestFlag {
|
||||
public:
|
||||
InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
|
||||
int a_write_fd)
|
||||
: file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {}
|
||||
|
||||
~InternalRunDeathTestFlag() {
|
||||
if (write_fd_ >= 0) posix::Close(write_fd_);
|
||||
}
|
||||
|
||||
const std::string& file() const { return file_; }
|
||||
int line() const { return line_; }
|
||||
int index() const { return index_; }
|
||||
int write_fd() const { return write_fd_; }
|
||||
|
||||
private:
|
||||
std::string file_;
|
||||
int line_;
|
||||
int index_;
|
||||
int write_fd_;
|
||||
|
||||
InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete;
|
||||
InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete;
|
||||
};
|
||||
|
||||
// Returns a newly created InternalRunDeathTestFlag object with fields
|
||||
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||
// the flag is specified; otherwise returns NULL.
|
||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
||||
@ -0,0 +1,227 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Google Test filepath utilities
|
||||
//
|
||||
// This header file declares classes and functions used internally by
|
||||
// Google Test. They are subject to change without notice.
|
||||
//
|
||||
// This file is #included in gtest/internal/gtest-internal.h.
|
||||
// Do not include this header file separately!
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// FilePath - a class for file and directory pathname manipulation which
|
||||
// handles platform-specific conventions (like the pathname separator).
|
||||
// Used for helper functions for naming files in a directory for xml output.
|
||||
// Except for Set methods, all methods are const or static, which provides an
|
||||
// "immutable value object" -- useful for peace of mind.
|
||||
// A FilePath with a value ending in a path separator ("like/this/") represents
|
||||
// a directory, otherwise it is assumed to represent a file. In either case,
|
||||
// it may or may not represent an actual file or directory in the file system.
|
||||
// Names are NOT checked for syntax correctness -- no checking for illegal
|
||||
// characters, malformed paths, etc.
|
||||
|
||||
class GTEST_API_ FilePath {
|
||||
public:
|
||||
FilePath() : pathname_("") {}
|
||||
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
|
||||
|
||||
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
|
||||
Normalize();
|
||||
}
|
||||
|
||||
FilePath& operator=(const FilePath& rhs) {
|
||||
Set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
|
||||
|
||||
const std::string& string() const { return pathname_; }
|
||||
const char* c_str() const { return pathname_.c_str(); }
|
||||
|
||||
// Returns the current working directory, or "" if unsuccessful.
|
||||
static FilePath GetCurrentDir();
|
||||
|
||||
// Given directory = "dir", base_name = "test", number = 0,
|
||||
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||
// On Windows platform, uses \ as the separator rather than /.
|
||||
static FilePath MakeFileName(const FilePath& directory,
|
||||
const FilePath& base_name, int number,
|
||||
const char* extension);
|
||||
|
||||
// Given directory = "dir", relative_path = "test.xml",
|
||||
// returns "dir/test.xml".
|
||||
// On Windows, uses \ as the separator rather than /.
|
||||
static FilePath ConcatPaths(const FilePath& directory,
|
||||
const FilePath& relative_path);
|
||||
|
||||
// Returns a pathname for a file that does not currently exist. The pathname
|
||||
// will be directory/base_name.extension or
|
||||
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||
// already exists. The number will be incremented until a pathname is found
|
||||
// that does not already exist.
|
||||
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||
// There could be a race condition if two or more processes are calling this
|
||||
// function at the same time -- they could both pick the same filename.
|
||||
static FilePath GenerateUniqueFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
const char* extension);
|
||||
|
||||
// Returns true if and only if the path is "".
|
||||
bool IsEmpty() const { return pathname_.empty(); }
|
||||
|
||||
// If input name has a trailing separator character, removes it and returns
|
||||
// the name, otherwise return the name string unmodified.
|
||||
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
FilePath RemoveTrailingPathSeparator() const;
|
||||
|
||||
// Returns a copy of the FilePath with the directory part removed.
|
||||
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||
// returns an empty FilePath ("").
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath RemoveDirectoryName() const;
|
||||
|
||||
// RemoveFileName returns the directory path with the filename removed.
|
||||
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath RemoveFileName() const;
|
||||
|
||||
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||
// found, returns a copy of the original FilePath.
|
||||
FilePath RemoveExtension(const char* extension) const;
|
||||
|
||||
// Creates directories so that path exists. Returns true if successful or if
|
||||
// the directories already exist; returns false if unable to create
|
||||
// directories for any reason. Will also return false if the FilePath does
|
||||
// not represent a directory (that is, it doesn't end with a path separator).
|
||||
bool CreateDirectoriesRecursively() const;
|
||||
|
||||
// Create the directory so that path exists. Returns true if successful or
|
||||
// if the directory already exists; returns false if unable to create the
|
||||
// directory for any reason, including if the parent directory does not
|
||||
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
bool CreateFolder() const;
|
||||
|
||||
// Returns true if FilePath describes something in the file-system,
|
||||
// either a file, directory, or whatever, and that something exists.
|
||||
bool FileOrDirectoryExists() const;
|
||||
|
||||
// Returns true if pathname describes a directory in the file-system
|
||||
// that exists.
|
||||
bool DirectoryExists() const;
|
||||
|
||||
// Returns true if FilePath ends with a path separator, which indicates that
|
||||
// it is intended to represent a directory. Returns false otherwise.
|
||||
// This does NOT check that a directory (or file) actually exists.
|
||||
bool IsDirectory() const;
|
||||
|
||||
// Returns true if pathname describes a root directory. (Windows has one
|
||||
// root directory per disk drive.)
|
||||
bool IsRootDirectory() const;
|
||||
|
||||
// Returns true if pathname describes an absolute path.
|
||||
bool IsAbsolutePath() const;
|
||||
|
||||
private:
|
||||
// Replaces multiple consecutive separators with a single separator.
|
||||
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||
// redundancies that might be in a pathname involving "." or "..".
|
||||
//
|
||||
// A pathname with multiple consecutive separators may occur either through
|
||||
// user error or as a result of some scripts or APIs that generate a pathname
|
||||
// with a trailing separator. On other platforms the same API or script
|
||||
// may NOT generate a pathname with a trailing "/". Then elsewhere that
|
||||
// pathname may have another "/" and pathname components added to it,
|
||||
// without checking for the separator already being there.
|
||||
// The script language and operating system may allow paths like "foo//bar"
|
||||
// but some of the functions in FilePath will not handle that correctly. In
|
||||
// particular, RemoveTrailingPathSeparator() only removes one separator, and
|
||||
// it is called in CreateDirectoriesRecursively() assuming that it will change
|
||||
// a pathname from directory syntax (trailing separator) to filename syntax.
|
||||
//
|
||||
// On Windows this method also replaces the alternate path separator '/' with
|
||||
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
|
||||
// "bar\\foo".
|
||||
|
||||
void Normalize();
|
||||
|
||||
// Returns a pointer to the last occurrence of a valid path separator in
|
||||
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||
// separators. Returns NULL if no path separator was found.
|
||||
const char* FindLastPathSeparator() const;
|
||||
|
||||
// Returns the length of the path root, including the directory separator at
|
||||
// the end of the prefix. Returns zero by definition if the path is relative.
|
||||
// Examples:
|
||||
// - [Windows] "..\Sibling" => 0
|
||||
// - [Windows] "\Windows" => 1
|
||||
// - [Windows] "C:/Windows\Notepad.exe" => 3
|
||||
// - [Windows] "\\Host\Share\C$/Windows" => 13
|
||||
// - [UNIX] "/bin" => 1
|
||||
size_t CalculateRootLength() const;
|
||||
|
||||
std::string pathname_;
|
||||
}; // class FilePath
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
|
||||
|
||||
#endif // GTEST_HAS_FILE_SYSTEM
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,122 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// This header file defines the GTEST_OS_* macro.
|
||||
// It is separate from gtest-port.h so that custom/gtest-port.h can include it.
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||
|
||||
// Determines the platform on which Google Test is compiled.
|
||||
#ifdef __CYGWIN__
|
||||
#define GTEST_OS_CYGWIN 1
|
||||
#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define GTEST_OS_WINDOWS_MINGW 1
|
||||
#define GTEST_OS_WINDOWS 1
|
||||
#elif defined _WIN32
|
||||
#define GTEST_OS_WINDOWS 1
|
||||
#ifdef _WIN32_WCE
|
||||
#define GTEST_OS_WINDOWS_MOBILE 1
|
||||
#elif defined(WINAPI_FAMILY)
|
||||
#include <winapifamily.h>
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
#define GTEST_OS_WINDOWS_DESKTOP 1
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
|
||||
#define GTEST_OS_WINDOWS_PHONE 1
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||
#define GTEST_OS_WINDOWS_RT 1
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
|
||||
#define GTEST_OS_WINDOWS_PHONE 1
|
||||
#define GTEST_OS_WINDOWS_TV_TITLE 1
|
||||
#else
|
||||
// WINAPI_FAMILY defined but no known partition matched.
|
||||
// Default to desktop.
|
||||
#define GTEST_OS_WINDOWS_DESKTOP 1
|
||||
#endif
|
||||
#else
|
||||
#define GTEST_OS_WINDOWS_DESKTOP 1
|
||||
#endif // _WIN32_WCE
|
||||
#elif defined __OS2__
|
||||
#define GTEST_OS_OS2 1
|
||||
#elif defined __APPLE__
|
||||
#define GTEST_OS_MAC 1
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
#define GTEST_OS_IOS 1
|
||||
#endif
|
||||
#elif defined __DragonFly__
|
||||
#define GTEST_OS_DRAGONFLY 1
|
||||
#elif defined __FreeBSD__
|
||||
#define GTEST_OS_FREEBSD 1
|
||||
#elif defined __Fuchsia__
|
||||
#define GTEST_OS_FUCHSIA 1
|
||||
#elif defined(__GNU__)
|
||||
#define GTEST_OS_GNU_HURD 1
|
||||
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
|
||||
#define GTEST_OS_GNU_KFREEBSD 1
|
||||
#elif defined __linux__
|
||||
#define GTEST_OS_LINUX 1
|
||||
#if defined __ANDROID__
|
||||
#define GTEST_OS_LINUX_ANDROID 1
|
||||
#endif
|
||||
#elif defined __MVS__
|
||||
#define GTEST_OS_ZOS 1
|
||||
#elif defined(__sun) && defined(__SVR4)
|
||||
#define GTEST_OS_SOLARIS 1
|
||||
#elif defined(_AIX)
|
||||
#define GTEST_OS_AIX 1
|
||||
#elif defined(__hpux)
|
||||
#define GTEST_OS_HPUX 1
|
||||
#elif defined __native_client__
|
||||
#define GTEST_OS_NACL 1
|
||||
#elif defined __NetBSD__
|
||||
#define GTEST_OS_NETBSD 1
|
||||
#elif defined __OpenBSD__
|
||||
#define GTEST_OS_OPENBSD 1
|
||||
#elif defined __QNX__
|
||||
#define GTEST_OS_QNX 1
|
||||
#elif defined(__HAIKU__)
|
||||
#define GTEST_OS_HAIKU 1
|
||||
#elif defined ESP8266
|
||||
#define GTEST_OS_ESP8266 1
|
||||
#elif defined ESP32
|
||||
#define GTEST_OS_ESP32 1
|
||||
#elif defined(__XTENSA__)
|
||||
#define GTEST_OS_XTENSA 1
|
||||
#elif defined(__hexagon__)
|
||||
#define GTEST_OS_QURT 1
|
||||
#elif defined(CPU_QN9090) || defined(CPU_QN9090HN)
|
||||
#define GTEST_OS_NXP_QN9090 1
|
||||
#elif defined(NRF52)
|
||||
#define GTEST_OS_NRF52 1
|
||||
#endif // __CYGWIN__
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,178 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The Google C++ Testing and Mocking Framework (Google Test)
|
||||
//
|
||||
// This header file declares the String class and functions used internally by
|
||||
// Google Test. They are subject to change without notice. They should not used
|
||||
// by code external to Google Test.
|
||||
//
|
||||
// This header file is #included by gtest-internal.h.
|
||||
// It should not be #included by other files.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// string.h is not guaranteed to provide strcpy on C++ Builder.
|
||||
#include <mem.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// String - an abstract class holding static string utilities.
|
||||
class GTEST_API_ String {
|
||||
public:
|
||||
// Static utility methods
|
||||
|
||||
// Clones a 0-terminated C string, allocating memory using new. The
|
||||
// caller is responsible for deleting the return value using
|
||||
// delete[]. Returns the cloned string, or NULL if the input is
|
||||
// NULL.
|
||||
//
|
||||
// This is different from strdup() in string.h, which allocates
|
||||
// memory using malloc().
|
||||
static const char* CloneCString(const char* c_str);
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
||||
// able to pass strings to Win32 APIs on CE we need to convert them
|
||||
// to 'Unicode', UTF-16.
|
||||
|
||||
// Creates a UTF-16 wide string from the given ANSI string, allocating
|
||||
// memory using new. The caller is responsible for deleting the return
|
||||
// value using delete[]. Returns the wide string, or NULL if the
|
||||
// input is NULL.
|
||||
//
|
||||
// The wide string is created using the ANSI codepage (CP_ACP) to
|
||||
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
// C runtime.
|
||||
static LPCWSTR AnsiToUtf16(const char* c_str);
|
||||
|
||||
// Creates an ANSI string from the given wide string, allocating
|
||||
// memory using new. The caller is responsible for deleting the return
|
||||
// value using delete[]. Returns the ANSI string, or NULL if the
|
||||
// input is NULL.
|
||||
//
|
||||
// The returned string is created using the ANSI codepage (CP_ACP) to
|
||||
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
// C runtime.
|
||||
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
|
||||
#endif
|
||||
|
||||
// Compares two C strings. Returns true if and only if they have the same
|
||||
// content.
|
||||
//
|
||||
// Unlike strcmp(), this function can handle NULL argument(s). A
|
||||
// NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool CStringEquals(const char* lhs, const char* rhs);
|
||||
|
||||
// Converts a wide C string to a String using the UTF-8 encoding.
|
||||
// NULL will be converted to "(null)". If an error occurred during
|
||||
// the conversion, "(failed to convert from wide string)" is
|
||||
// returned.
|
||||
static std::string ShowWideCString(const wchar_t* wide_c_str);
|
||||
|
||||
// Compares two wide C strings. Returns true if and only if they have the
|
||||
// same content.
|
||||
//
|
||||
// Unlike wcscmp(), this function can handle NULL argument(s). A
|
||||
// NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
|
||||
|
||||
// Compares two C strings, ignoring case. Returns true if and only if
|
||||
// they have the same content.
|
||||
//
|
||||
// Unlike strcasecmp(), this function can handle NULL argument(s).
|
||||
// A NULL C string is considered different to any non-NULL C string,
|
||||
// including the empty string.
|
||||
static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs);
|
||||
|
||||
// Compares two wide C strings, ignoring case. Returns true if and only if
|
||||
// they have the same content.
|
||||
//
|
||||
// Unlike wcscasecmp(), this function can handle NULL argument(s).
|
||||
// A NULL C string is considered different to any non-NULL wide C string,
|
||||
// including the empty string.
|
||||
// NB: The implementations on different platforms slightly differ.
|
||||
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
|
||||
// environment variable. On GNU platform this method uses wcscasecmp
|
||||
// which compares according to LC_CTYPE category of the current locale.
|
||||
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
|
||||
// current locale.
|
||||
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
|
||||
const wchar_t* rhs);
|
||||
|
||||
// Returns true if and only if the given string ends with the given suffix,
|
||||
// ignoring case. Any string is considered to end with an empty suffix.
|
||||
static bool EndsWithCaseInsensitive(const std::string& str,
|
||||
const std::string& suffix);
|
||||
|
||||
// Formats an int value as "%02d".
|
||||
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
|
||||
|
||||
// Formats an int value to given width with leading zeros.
|
||||
static std::string FormatIntWidthN(int value, int width);
|
||||
|
||||
// Formats an int value as "%X".
|
||||
static std::string FormatHexInt(int value);
|
||||
|
||||
// Formats an int value as "%X".
|
||||
static std::string FormatHexUInt32(uint32_t value);
|
||||
|
||||
// Formats a byte as "%02X".
|
||||
static std::string FormatByte(unsigned char value);
|
||||
|
||||
private:
|
||||
String(); // Not meant to be instantiated.
|
||||
}; // class String
|
||||
|
||||
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
||||
// character in the buffer is replaced with "\\0".
|
||||
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
||||
@ -0,0 +1,220 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Type utilities needed for implementing typed and type-parameterized
|
||||
// tests.
|
||||
|
||||
// IWYU pragma: private, include "gtest/gtest.h"
|
||||
// IWYU pragma: friend gtest/.*
|
||||
// IWYU pragma: friend gmock/.*
|
||||
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
||||
// libstdc++ (which is where cxxabi.h comes from).
|
||||
#if GTEST_HAS_CXXABI_H_
|
||||
#include <cxxabi.h>
|
||||
#elif defined(__HP_aCC)
|
||||
#include <acxx_demangle.h>
|
||||
#endif // GTEST_HASH_CXXABI_H_
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// Canonicalizes a given name with respect to the Standard C++ Library.
|
||||
// This handles removing the inline namespace within `std` that is
|
||||
// used by various standard libraries (e.g., `std::__1`). Names outside
|
||||
// of namespace std are returned unmodified.
|
||||
inline std::string CanonicalizeForStdLibVersioning(std::string s) {
|
||||
static const char prefix[] = "std::__";
|
||||
if (s.compare(0, strlen(prefix), prefix) == 0) {
|
||||
std::string::size_type end = s.find("::", strlen(prefix));
|
||||
if (end != s.npos) {
|
||||
// Erase everything between the initial `std` and the second `::`.
|
||||
s.erase(strlen("std"), end - strlen("std"));
|
||||
}
|
||||
}
|
||||
|
||||
// Strip redundant spaces in typename to match MSVC
|
||||
// For example, std::pair<int, bool> -> std::pair<int,bool>
|
||||
static const char to_search[] = ", ";
|
||||
static const char replace_str[] = ",";
|
||||
size_t pos = 0;
|
||||
while (true) {
|
||||
// Get the next occurrence from the current position
|
||||
pos = s.find(to_search, pos);
|
||||
if (pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
// Replace this occurrence of substring
|
||||
s.replace(pos, strlen(to_search), replace_str);
|
||||
pos += strlen(replace_str);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#if GTEST_HAS_RTTI
|
||||
// GetTypeName(const std::type_info&) returns a human-readable name of type T.
|
||||
inline std::string GetTypeName(const std::type_info& type) {
|
||||
const char* const name = type.name();
|
||||
#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
|
||||
int status = 0;
|
||||
// gcc's implementation of typeid(T).name() mangles the type name,
|
||||
// so we have to demangle it.
|
||||
#if GTEST_HAS_CXXABI_H_
|
||||
using abi::__cxa_demangle;
|
||||
#endif // GTEST_HAS_CXXABI_H_
|
||||
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
|
||||
const std::string name_str(status == 0 ? readable_name : name);
|
||||
free(readable_name);
|
||||
return CanonicalizeForStdLibVersioning(name_str);
|
||||
#elif defined(_MSC_VER)
|
||||
// Strip struct and class due to differences between
|
||||
// MSVC and other compilers. std::pair<int,bool> is printed as
|
||||
// "struct std::pair<int,bool>" when using MSVC vs "std::pair<int, bool>" with
|
||||
// other compilers.
|
||||
std::string s = name;
|
||||
// Only strip the leading "struct " and "class ", so uses rfind == 0 to
|
||||
// ensure that
|
||||
if (s.rfind("struct ", 0) == 0) {
|
||||
s = s.substr(strlen("struct "));
|
||||
} else if (s.rfind("class ", 0) == 0) {
|
||||
s = s.substr(strlen("class "));
|
||||
}
|
||||
return s;
|
||||
#else
|
||||
return name;
|
||||
#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
||||
}
|
||||
#endif // GTEST_HAS_RTTI
|
||||
|
||||
// GetTypeName<T>() returns a human-readable name of type T if and only if
|
||||
// RTTI is enabled, otherwise it returns a dummy type name.
|
||||
// NB: This function is also used in Google Mock, so don't move it inside of
|
||||
// the typed-test-only section below.
|
||||
template <typename T>
|
||||
std::string GetTypeName() {
|
||||
#if GTEST_HAS_RTTI
|
||||
return GetTypeName(typeid(T));
|
||||
#else
|
||||
return "<type>";
|
||||
#endif // GTEST_HAS_RTTI
|
||||
}
|
||||
|
||||
// A unique type indicating an empty node
|
||||
struct None {};
|
||||
|
||||
#define GTEST_TEMPLATE_ \
|
||||
template <typename T> \
|
||||
class
|
||||
|
||||
// The template "selector" struct TemplateSel<Tmpl> is used to
|
||||
// represent Tmpl, which must be a class template with one type
|
||||
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
|
||||
// as the type Tmpl<T>. This allows us to actually instantiate the
|
||||
// template "selected" by TemplateSel<Tmpl>.
|
||||
//
|
||||
// This trick is necessary for simulating typedef for class templates,
|
||||
// which C++ doesn't support directly.
|
||||
template <GTEST_TEMPLATE_ Tmpl>
|
||||
struct TemplateSel {
|
||||
template <typename T>
|
||||
struct Bind {
|
||||
typedef Tmpl<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
#define GTEST_BIND_(TmplSel, T) TmplSel::template Bind<T>::type
|
||||
|
||||
template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>
|
||||
struct Templates {
|
||||
using Head = TemplateSel<Head_>;
|
||||
using Tail = Templates<Tail_...>;
|
||||
};
|
||||
|
||||
template <GTEST_TEMPLATE_ Head_>
|
||||
struct Templates<Head_> {
|
||||
using Head = TemplateSel<Head_>;
|
||||
using Tail = None;
|
||||
};
|
||||
|
||||
// Tuple-like type lists
|
||||
template <typename Head_, typename... Tail_>
|
||||
struct Types {
|
||||
using Head = Head_;
|
||||
using Tail = Types<Tail_...>;
|
||||
};
|
||||
|
||||
template <typename Head_>
|
||||
struct Types<Head_> {
|
||||
using Head = Head_;
|
||||
using Tail = None;
|
||||
};
|
||||
|
||||
// Helper metafunctions to tell apart a single type from types
|
||||
// generated by ::testing::Types
|
||||
template <typename... Ts>
|
||||
struct ProxyTypeList {
|
||||
using type = Types<Ts...>;
|
||||
};
|
||||
|
||||
template <typename>
|
||||
struct is_proxy_type_list : std::false_type {};
|
||||
|
||||
template <typename... Ts>
|
||||
struct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {};
|
||||
|
||||
// Generator which conditionally creates type lists.
|
||||
// It recognizes if a requested type list should be created
|
||||
// and prevents creating a new type list nested within another one.
|
||||
template <typename T>
|
||||
struct GenerateTypeList {
|
||||
private:
|
||||
using proxy = typename std::conditional<is_proxy_type_list<T>::value, T,
|
||||
ProxyTypeList<T>>::type;
|
||||
|
||||
public:
|
||||
using type = typename proxy::type;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename... Ts>
|
||||
using Types = internal::ProxyTypeList<Ts...>;
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
|
||||
@ -0,0 +1,114 @@
|
||||
// Copyright 2009 The RE2 Authors. All Rights Reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef RE2_FILTERED_RE2_H_
|
||||
#define RE2_FILTERED_RE2_H_
|
||||
|
||||
// The class FilteredRE2 is used as a wrapper to multiple RE2 regexps.
|
||||
// It provides a prefilter mechanism that helps in cutting down the
|
||||
// number of regexps that need to be actually searched.
|
||||
//
|
||||
// By design, it does not include a string matching engine. This is to
|
||||
// allow the user of the class to use their favorite string matching
|
||||
// engine. The overall flow is: Add all the regexps using Add, then
|
||||
// Compile the FilteredRE2. Compile returns strings that need to be
|
||||
// matched. Note that the returned strings are lowercased and distinct.
|
||||
// For applying regexps to a search text, the caller does the string
|
||||
// matching using the returned strings. When doing the string match,
|
||||
// note that the caller has to do that in a case-insensitive way or
|
||||
// on a lowercased version of the search text. Then call FirstMatch
|
||||
// or AllMatches with a vector of indices of strings that were found
|
||||
// in the text to get the actual regexp matches.
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "re2/re2.h"
|
||||
|
||||
namespace re2 {
|
||||
|
||||
class PrefilterTree;
|
||||
|
||||
class FilteredRE2 {
|
||||
public:
|
||||
FilteredRE2();
|
||||
explicit FilteredRE2(int min_atom_len);
|
||||
~FilteredRE2();
|
||||
|
||||
// Not copyable.
|
||||
FilteredRE2(const FilteredRE2&) = delete;
|
||||
FilteredRE2& operator=(const FilteredRE2&) = delete;
|
||||
// Movable.
|
||||
FilteredRE2(FilteredRE2&& other);
|
||||
FilteredRE2& operator=(FilteredRE2&& other);
|
||||
|
||||
// Uses RE2 constructor to create a RE2 object (re). Returns
|
||||
// re->error_code(). If error_code is other than NoError, then re is
|
||||
// deleted and not added to re2_vec_.
|
||||
RE2::ErrorCode Add(const StringPiece& pattern,
|
||||
const RE2::Options& options,
|
||||
int* id);
|
||||
|
||||
// Prepares the regexps added by Add for filtering. Returns a set
|
||||
// of strings that the caller should check for in candidate texts.
|
||||
// The returned strings are lowercased and distinct. When doing
|
||||
// string matching, it should be performed in a case-insensitive
|
||||
// way or the search text should be lowercased first. Call after
|
||||
// all Add calls are done.
|
||||
void Compile(std::vector<std::string>* strings_to_match);
|
||||
|
||||
// Returns the index of the first matching regexp.
|
||||
// Returns -1 on no match. Can be called prior to Compile.
|
||||
// Does not do any filtering: simply tries to Match the
|
||||
// regexps in a loop.
|
||||
int SlowFirstMatch(const StringPiece& text) const;
|
||||
|
||||
// Returns the index of the first matching regexp.
|
||||
// Returns -1 on no match. Compile has to be called before
|
||||
// calling this.
|
||||
int FirstMatch(const StringPiece& text,
|
||||
const std::vector<int>& atoms) const;
|
||||
|
||||
// Returns the indices of all matching regexps, after first clearing
|
||||
// matched_regexps.
|
||||
bool AllMatches(const StringPiece& text,
|
||||
const std::vector<int>& atoms,
|
||||
std::vector<int>* matching_regexps) const;
|
||||
|
||||
// Returns the indices of all potentially matching regexps after first
|
||||
// clearing potential_regexps.
|
||||
// A regexp is potentially matching if it passes the filter.
|
||||
// If a regexp passes the filter it may still not match.
|
||||
// A regexp that does not pass the filter is guaranteed to not match.
|
||||
void AllPotentials(const std::vector<int>& atoms,
|
||||
std::vector<int>* potential_regexps) const;
|
||||
|
||||
// The number of regexps added.
|
||||
int NumRegexps() const { return static_cast<int>(re2_vec_.size()); }
|
||||
|
||||
// Get the individual RE2 objects.
|
||||
const RE2& GetRE2(int regexpid) const { return *re2_vec_[regexpid]; }
|
||||
|
||||
private:
|
||||
// Print prefilter.
|
||||
void PrintPrefilter(int regexpid);
|
||||
|
||||
// Useful for testing and debugging.
|
||||
void RegexpsGivenStrings(const std::vector<int>& matched_atoms,
|
||||
std::vector<int>* passed_regexps);
|
||||
|
||||
// All the regexps in the FilteredRE2.
|
||||
std::vector<RE2*> re2_vec_;
|
||||
|
||||
// Has the FilteredRE2 been compiled using Compile()
|
||||
bool compiled_;
|
||||
|
||||
// An AND-OR tree of string atoms used for filtering regexps.
|
||||
std::unique_ptr<PrefilterTree> prefilter_tree_;
|
||||
};
|
||||
|
||||
} // namespace re2
|
||||
|
||||
#endif // RE2_FILTERED_RE2_H_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,85 @@
|
||||
// Copyright 2010 The RE2 Authors. All Rights Reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef RE2_SET_H_
|
||||
#define RE2_SET_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "re2/re2.h"
|
||||
|
||||
namespace re2 {
|
||||
class Prog;
|
||||
class Regexp;
|
||||
} // namespace re2
|
||||
|
||||
namespace re2 {
|
||||
|
||||
// An RE2::Set represents a collection of regexps that can
|
||||
// be searched for simultaneously.
|
||||
class RE2::Set {
|
||||
public:
|
||||
enum ErrorKind {
|
||||
kNoError = 0,
|
||||
kNotCompiled, // The set is not compiled.
|
||||
kOutOfMemory, // The DFA ran out of memory.
|
||||
kInconsistent, // The result is inconsistent. This should never happen.
|
||||
};
|
||||
|
||||
struct ErrorInfo {
|
||||
ErrorKind kind;
|
||||
};
|
||||
|
||||
Set(const RE2::Options& options, RE2::Anchor anchor);
|
||||
~Set();
|
||||
|
||||
// Not copyable.
|
||||
Set(const Set&) = delete;
|
||||
Set& operator=(const Set&) = delete;
|
||||
// Movable.
|
||||
Set(Set&& other);
|
||||
Set& operator=(Set&& other);
|
||||
|
||||
// Adds pattern to the set using the options passed to the constructor.
|
||||
// Returns the index that will identify the regexp in the output of Match(),
|
||||
// or -1 if the regexp cannot be parsed.
|
||||
// Indices are assigned in sequential order starting from 0.
|
||||
// Errors do not increment the index; if error is not NULL, *error will hold
|
||||
// the error message from the parser.
|
||||
int Add(const StringPiece& pattern, std::string* error);
|
||||
|
||||
// Compiles the set in preparation for matching.
|
||||
// Returns false if the compiler runs out of memory.
|
||||
// Add() must not be called again after Compile().
|
||||
// Compile() must be called before Match().
|
||||
bool Compile();
|
||||
|
||||
// Returns true if text matches at least one of the regexps in the set.
|
||||
// Fills v (if not NULL) with the indices of the matching regexps.
|
||||
// Callers must not expect v to be sorted.
|
||||
bool Match(const StringPiece& text, std::vector<int>* v) const;
|
||||
|
||||
// As above, but populates error_info (if not NULL) when none of the regexps
|
||||
// in the set matched. This can inform callers when DFA execution fails, for
|
||||
// example, because they might wish to handle that case differently.
|
||||
bool Match(const StringPiece& text, std::vector<int>* v,
|
||||
ErrorInfo* error_info) const;
|
||||
|
||||
private:
|
||||
typedef std::pair<std::string, re2::Regexp*> Elem;
|
||||
|
||||
RE2::Options options_;
|
||||
RE2::Anchor anchor_;
|
||||
std::vector<Elem> elem_;
|
||||
bool compiled_;
|
||||
int size_;
|
||||
std::unique_ptr<re2::Prog> prog_;
|
||||
};
|
||||
|
||||
} // namespace re2
|
||||
|
||||
#endif // RE2_SET_H_
|
||||
@ -0,0 +1,213 @@
|
||||
// Copyright 2001-2010 The RE2 Authors. All Rights Reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef RE2_STRINGPIECE_H_
|
||||
#define RE2_STRINGPIECE_H_
|
||||
|
||||
// A string-like object that points to a sized piece of memory.
|
||||
//
|
||||
// Functions or methods may use const StringPiece& parameters to accept either
|
||||
// a "const char*" or a "string" value that will be implicitly converted to
|
||||
// a StringPiece. The implicit conversion means that it is often appropriate
|
||||
// to include this .h file in other files rather than forward-declaring
|
||||
// StringPiece as would be appropriate for most other Google classes.
|
||||
//
|
||||
// Systematic usage of StringPiece is encouraged as it will reduce unnecessary
|
||||
// conversions from "const char*" to "string" and back again.
|
||||
//
|
||||
//
|
||||
// Arghh! I wish C++ literals were "string".
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <iosfwd>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#ifdef __cpp_lib_string_view
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
namespace re2 {
|
||||
|
||||
class StringPiece {
|
||||
public:
|
||||
typedef std::char_traits<char> traits_type;
|
||||
typedef char value_type;
|
||||
typedef char* pointer;
|
||||
typedef const char* const_pointer;
|
||||
typedef char& reference;
|
||||
typedef const char& const_reference;
|
||||
typedef const char* const_iterator;
|
||||
typedef const_iterator iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef const_reverse_iterator reverse_iterator;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
static const size_type npos = static_cast<size_type>(-1);
|
||||
|
||||
// We provide non-explicit singleton constructors so users can pass
|
||||
// in a "const char*" or a "string" wherever a "StringPiece" is
|
||||
// expected.
|
||||
StringPiece()
|
||||
: data_(NULL), size_(0) {}
|
||||
#ifdef __cpp_lib_string_view
|
||||
StringPiece(const std::string_view& str)
|
||||
: data_(str.data()), size_(str.size()) {}
|
||||
#endif
|
||||
StringPiece(const std::string& str)
|
||||
: data_(str.data()), size_(str.size()) {}
|
||||
StringPiece(const char* str)
|
||||
: data_(str), size_(str == NULL ? 0 : strlen(str)) {}
|
||||
StringPiece(const char* str, size_type len)
|
||||
: data_(str), size_(len) {}
|
||||
|
||||
const_iterator begin() const { return data_; }
|
||||
const_iterator end() const { return data_ + size_; }
|
||||
const_reverse_iterator rbegin() const {
|
||||
return const_reverse_iterator(data_ + size_);
|
||||
}
|
||||
const_reverse_iterator rend() const {
|
||||
return const_reverse_iterator(data_);
|
||||
}
|
||||
|
||||
size_type size() const { return size_; }
|
||||
size_type length() const { return size_; }
|
||||
bool empty() const { return size_ == 0; }
|
||||
|
||||
const_reference operator[](size_type i) const { return data_[i]; }
|
||||
const_pointer data() const { return data_; }
|
||||
|
||||
void remove_prefix(size_type n) {
|
||||
data_ += n;
|
||||
size_ -= n;
|
||||
}
|
||||
|
||||
void remove_suffix(size_type n) {
|
||||
size_ -= n;
|
||||
}
|
||||
|
||||
void set(const char* str) {
|
||||
data_ = str;
|
||||
size_ = str == NULL ? 0 : strlen(str);
|
||||
}
|
||||
|
||||
void set(const char* str, size_type len) {
|
||||
data_ = str;
|
||||
size_ = len;
|
||||
}
|
||||
|
||||
#ifdef __cpp_lib_string_view
|
||||
// Converts to `std::basic_string_view`.
|
||||
operator std::basic_string_view<char, traits_type>() const {
|
||||
if (!data_) return {};
|
||||
return std::basic_string_view<char, traits_type>(data_, size_);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Converts to `std::basic_string`.
|
||||
template <typename A>
|
||||
explicit operator std::basic_string<char, traits_type, A>() const {
|
||||
if (!data_) return {};
|
||||
return std::basic_string<char, traits_type, A>(data_, size_);
|
||||
}
|
||||
|
||||
std::string as_string() const {
|
||||
return std::string(data_, size_);
|
||||
}
|
||||
|
||||
// We also define ToString() here, since many other string-like
|
||||
// interfaces name the routine that converts to a C++ string
|
||||
// "ToString", and it's confusing to have the method that does that
|
||||
// for a StringPiece be called "as_string()". We also leave the
|
||||
// "as_string()" method defined here for existing code.
|
||||
std::string ToString() const {
|
||||
return std::string(data_, size_);
|
||||
}
|
||||
|
||||
void CopyToString(std::string* target) const {
|
||||
target->assign(data_, size_);
|
||||
}
|
||||
|
||||
void AppendToString(std::string* target) const {
|
||||
target->append(data_, size_);
|
||||
}
|
||||
|
||||
size_type copy(char* buf, size_type n, size_type pos = 0) const;
|
||||
StringPiece substr(size_type pos = 0, size_type n = npos) const;
|
||||
|
||||
int compare(const StringPiece& x) const {
|
||||
size_type min_size = std::min(size(), x.size());
|
||||
if (min_size > 0) {
|
||||
int r = memcmp(data(), x.data(), min_size);
|
||||
if (r < 0) return -1;
|
||||
if (r > 0) return 1;
|
||||
}
|
||||
if (size() < x.size()) return -1;
|
||||
if (size() > x.size()) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Does "this" start with "x"?
|
||||
bool starts_with(const StringPiece& x) const {
|
||||
return x.empty() ||
|
||||
(size() >= x.size() && memcmp(data(), x.data(), x.size()) == 0);
|
||||
}
|
||||
|
||||
// Does "this" end with "x"?
|
||||
bool ends_with(const StringPiece& x) const {
|
||||
return x.empty() ||
|
||||
(size() >= x.size() &&
|
||||
memcmp(data() + (size() - x.size()), x.data(), x.size()) == 0);
|
||||
}
|
||||
|
||||
bool contains(const StringPiece& s) const {
|
||||
return find(s) != npos;
|
||||
}
|
||||
|
||||
size_type find(const StringPiece& s, size_type pos = 0) const;
|
||||
size_type find(char c, size_type pos = 0) const;
|
||||
size_type rfind(const StringPiece& s, size_type pos = npos) const;
|
||||
size_type rfind(char c, size_type pos = npos) const;
|
||||
|
||||
private:
|
||||
const_pointer data_;
|
||||
size_type size_;
|
||||
};
|
||||
|
||||
inline bool operator==(const StringPiece& x, const StringPiece& y) {
|
||||
StringPiece::size_type len = x.size();
|
||||
if (len != y.size()) return false;
|
||||
return x.data() == y.data() || len == 0 ||
|
||||
memcmp(x.data(), y.data(), len) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const StringPiece& x, const StringPiece& y) {
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
inline bool operator<(const StringPiece& x, const StringPiece& y) {
|
||||
StringPiece::size_type min_size = std::min(x.size(), y.size());
|
||||
int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size);
|
||||
return (r < 0) || (r == 0 && x.size() < y.size());
|
||||
}
|
||||
|
||||
inline bool operator>(const StringPiece& x, const StringPiece& y) {
|
||||
return y < x;
|
||||
}
|
||||
|
||||
inline bool operator<=(const StringPiece& x, const StringPiece& y) {
|
||||
return !(x > y);
|
||||
}
|
||||
|
||||
inline bool operator>=(const StringPiece& x, const StringPiece& y) {
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
// Allow StringPiece to be logged.
|
||||
std::ostream& operator<<(std::ostream& o, const StringPiece& p);
|
||||
|
||||
} // namespace re2
|
||||
|
||||
#endif // RE2_STRINGPIECE_H_
|
||||
@ -0,0 +1,72 @@
|
||||
// Copyright 2018 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SHADERC_ENV_H_
|
||||
#define SHADERC_ENV_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
shaderc_target_env_vulkan, // SPIR-V under Vulkan semantics
|
||||
shaderc_target_env_opengl, // SPIR-V under OpenGL semantics
|
||||
// NOTE: SPIR-V code generation is not supported for shaders under OpenGL
|
||||
// compatibility profile.
|
||||
shaderc_target_env_opengl_compat, // SPIR-V under OpenGL semantics,
|
||||
// including compatibility profile
|
||||
// functions
|
||||
shaderc_target_env_webgpu, // Deprecated, SPIR-V under WebGPU
|
||||
// semantics
|
||||
shaderc_target_env_default = shaderc_target_env_vulkan
|
||||
} shaderc_target_env;
|
||||
|
||||
typedef enum {
|
||||
// For Vulkan, use Vulkan's mapping of version numbers to integers.
|
||||
// See vulkan.h
|
||||
shaderc_env_version_vulkan_1_0 = ((1u << 22)),
|
||||
shaderc_env_version_vulkan_1_1 = ((1u << 22) | (1 << 12)),
|
||||
shaderc_env_version_vulkan_1_2 = ((1u << 22) | (2 << 12)),
|
||||
shaderc_env_version_vulkan_1_3 = ((1u << 22) | (3 << 12)),
|
||||
// For OpenGL, use the number from #version in shaders.
|
||||
// TODO(dneto): Currently no difference between OpenGL 4.5 and 4.6.
|
||||
// See glslang/Standalone/Standalone.cpp
|
||||
// TODO(dneto): Glslang doesn't accept a OpenGL client version of 460.
|
||||
shaderc_env_version_opengl_4_5 = 450,
|
||||
shaderc_env_version_webgpu, // Deprecated, WebGPU env never defined versions
|
||||
} shaderc_env_version;
|
||||
|
||||
// The known versions of SPIR-V.
|
||||
typedef enum {
|
||||
// Use the values used for word 1 of a SPIR-V binary:
|
||||
// - bits 24 to 31: zero
|
||||
// - bits 16 to 23: major version number
|
||||
// - bits 8 to 15: minor version number
|
||||
// - bits 0 to 7: zero
|
||||
shaderc_spirv_version_1_0 = 0x010000u,
|
||||
shaderc_spirv_version_1_1 = 0x010100u,
|
||||
shaderc_spirv_version_1_2 = 0x010200u,
|
||||
shaderc_spirv_version_1_3 = 0x010300u,
|
||||
shaderc_spirv_version_1_4 = 0x010400u,
|
||||
shaderc_spirv_version_1_5 = 0x010500u,
|
||||
shaderc_spirv_version_1_6 = 0x010600u
|
||||
} shaderc_spirv_version;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // SHADERC_ENV_H_
|
||||
@ -0,0 +1,619 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SHADERC_SHADERC_H_
|
||||
#define SHADERC_SHADERC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "shaderc/env.h"
|
||||
#include "shaderc/status.h"
|
||||
#include "shaderc/visibility.h"
|
||||
|
||||
// Source language kind.
|
||||
typedef enum {
|
||||
shaderc_source_language_glsl,
|
||||
shaderc_source_language_hlsl,
|
||||
} shaderc_source_language;
|
||||
|
||||
typedef enum {
|
||||
// Forced shader kinds. These shader kinds force the compiler to compile the
|
||||
// source code as the specified kind of shader.
|
||||
shaderc_vertex_shader,
|
||||
shaderc_fragment_shader,
|
||||
shaderc_compute_shader,
|
||||
shaderc_geometry_shader,
|
||||
shaderc_tess_control_shader,
|
||||
shaderc_tess_evaluation_shader,
|
||||
|
||||
shaderc_glsl_vertex_shader = shaderc_vertex_shader,
|
||||
shaderc_glsl_fragment_shader = shaderc_fragment_shader,
|
||||
shaderc_glsl_compute_shader = shaderc_compute_shader,
|
||||
shaderc_glsl_geometry_shader = shaderc_geometry_shader,
|
||||
shaderc_glsl_tess_control_shader = shaderc_tess_control_shader,
|
||||
shaderc_glsl_tess_evaluation_shader = shaderc_tess_evaluation_shader,
|
||||
|
||||
// Deduce the shader kind from #pragma annotation in the source code. Compiler
|
||||
// will emit error if #pragma annotation is not found.
|
||||
shaderc_glsl_infer_from_source,
|
||||
// Default shader kinds. Compiler will fall back to compile the source code as
|
||||
// the specified kind of shader when #pragma annotation is not found in the
|
||||
// source code.
|
||||
shaderc_glsl_default_vertex_shader,
|
||||
shaderc_glsl_default_fragment_shader,
|
||||
shaderc_glsl_default_compute_shader,
|
||||
shaderc_glsl_default_geometry_shader,
|
||||
shaderc_glsl_default_tess_control_shader,
|
||||
shaderc_glsl_default_tess_evaluation_shader,
|
||||
shaderc_spirv_assembly,
|
||||
shaderc_raygen_shader,
|
||||
shaderc_anyhit_shader,
|
||||
shaderc_closesthit_shader,
|
||||
shaderc_miss_shader,
|
||||
shaderc_intersection_shader,
|
||||
shaderc_callable_shader,
|
||||
shaderc_glsl_raygen_shader = shaderc_raygen_shader,
|
||||
shaderc_glsl_anyhit_shader = shaderc_anyhit_shader,
|
||||
shaderc_glsl_closesthit_shader = shaderc_closesthit_shader,
|
||||
shaderc_glsl_miss_shader = shaderc_miss_shader,
|
||||
shaderc_glsl_intersection_shader = shaderc_intersection_shader,
|
||||
shaderc_glsl_callable_shader = shaderc_callable_shader,
|
||||
shaderc_glsl_default_raygen_shader,
|
||||
shaderc_glsl_default_anyhit_shader,
|
||||
shaderc_glsl_default_closesthit_shader,
|
||||
shaderc_glsl_default_miss_shader,
|
||||
shaderc_glsl_default_intersection_shader,
|
||||
shaderc_glsl_default_callable_shader,
|
||||
shaderc_task_shader,
|
||||
shaderc_mesh_shader,
|
||||
shaderc_glsl_task_shader = shaderc_task_shader,
|
||||
shaderc_glsl_mesh_shader = shaderc_mesh_shader,
|
||||
shaderc_glsl_default_task_shader,
|
||||
shaderc_glsl_default_mesh_shader,
|
||||
} shaderc_shader_kind;
|
||||
|
||||
typedef enum {
|
||||
shaderc_profile_none, // Used if and only if GLSL version did not specify
|
||||
// profiles.
|
||||
shaderc_profile_core,
|
||||
shaderc_profile_compatibility, // Disabled. This generates an error
|
||||
shaderc_profile_es,
|
||||
} shaderc_profile;
|
||||
|
||||
// Optimization level.
|
||||
typedef enum {
|
||||
shaderc_optimization_level_zero, // no optimization
|
||||
shaderc_optimization_level_size, // optimize towards reducing code size
|
||||
shaderc_optimization_level_performance, // optimize towards performance
|
||||
} shaderc_optimization_level;
|
||||
|
||||
// Resource limits.
|
||||
typedef enum {
|
||||
shaderc_limit_max_lights,
|
||||
shaderc_limit_max_clip_planes,
|
||||
shaderc_limit_max_texture_units,
|
||||
shaderc_limit_max_texture_coords,
|
||||
shaderc_limit_max_vertex_attribs,
|
||||
shaderc_limit_max_vertex_uniform_components,
|
||||
shaderc_limit_max_varying_floats,
|
||||
shaderc_limit_max_vertex_texture_image_units,
|
||||
shaderc_limit_max_combined_texture_image_units,
|
||||
shaderc_limit_max_texture_image_units,
|
||||
shaderc_limit_max_fragment_uniform_components,
|
||||
shaderc_limit_max_draw_buffers,
|
||||
shaderc_limit_max_vertex_uniform_vectors,
|
||||
shaderc_limit_max_varying_vectors,
|
||||
shaderc_limit_max_fragment_uniform_vectors,
|
||||
shaderc_limit_max_vertex_output_vectors,
|
||||
shaderc_limit_max_fragment_input_vectors,
|
||||
shaderc_limit_min_program_texel_offset,
|
||||
shaderc_limit_max_program_texel_offset,
|
||||
shaderc_limit_max_clip_distances,
|
||||
shaderc_limit_max_compute_work_group_count_x,
|
||||
shaderc_limit_max_compute_work_group_count_y,
|
||||
shaderc_limit_max_compute_work_group_count_z,
|
||||
shaderc_limit_max_compute_work_group_size_x,
|
||||
shaderc_limit_max_compute_work_group_size_y,
|
||||
shaderc_limit_max_compute_work_group_size_z,
|
||||
shaderc_limit_max_compute_uniform_components,
|
||||
shaderc_limit_max_compute_texture_image_units,
|
||||
shaderc_limit_max_compute_image_uniforms,
|
||||
shaderc_limit_max_compute_atomic_counters,
|
||||
shaderc_limit_max_compute_atomic_counter_buffers,
|
||||
shaderc_limit_max_varying_components,
|
||||
shaderc_limit_max_vertex_output_components,
|
||||
shaderc_limit_max_geometry_input_components,
|
||||
shaderc_limit_max_geometry_output_components,
|
||||
shaderc_limit_max_fragment_input_components,
|
||||
shaderc_limit_max_image_units,
|
||||
shaderc_limit_max_combined_image_units_and_fragment_outputs,
|
||||
shaderc_limit_max_combined_shader_output_resources,
|
||||
shaderc_limit_max_image_samples,
|
||||
shaderc_limit_max_vertex_image_uniforms,
|
||||
shaderc_limit_max_tess_control_image_uniforms,
|
||||
shaderc_limit_max_tess_evaluation_image_uniforms,
|
||||
shaderc_limit_max_geometry_image_uniforms,
|
||||
shaderc_limit_max_fragment_image_uniforms,
|
||||
shaderc_limit_max_combined_image_uniforms,
|
||||
shaderc_limit_max_geometry_texture_image_units,
|
||||
shaderc_limit_max_geometry_output_vertices,
|
||||
shaderc_limit_max_geometry_total_output_components,
|
||||
shaderc_limit_max_geometry_uniform_components,
|
||||
shaderc_limit_max_geometry_varying_components,
|
||||
shaderc_limit_max_tess_control_input_components,
|
||||
shaderc_limit_max_tess_control_output_components,
|
||||
shaderc_limit_max_tess_control_texture_image_units,
|
||||
shaderc_limit_max_tess_control_uniform_components,
|
||||
shaderc_limit_max_tess_control_total_output_components,
|
||||
shaderc_limit_max_tess_evaluation_input_components,
|
||||
shaderc_limit_max_tess_evaluation_output_components,
|
||||
shaderc_limit_max_tess_evaluation_texture_image_units,
|
||||
shaderc_limit_max_tess_evaluation_uniform_components,
|
||||
shaderc_limit_max_tess_patch_components,
|
||||
shaderc_limit_max_patch_vertices,
|
||||
shaderc_limit_max_tess_gen_level,
|
||||
shaderc_limit_max_viewports,
|
||||
shaderc_limit_max_vertex_atomic_counters,
|
||||
shaderc_limit_max_tess_control_atomic_counters,
|
||||
shaderc_limit_max_tess_evaluation_atomic_counters,
|
||||
shaderc_limit_max_geometry_atomic_counters,
|
||||
shaderc_limit_max_fragment_atomic_counters,
|
||||
shaderc_limit_max_combined_atomic_counters,
|
||||
shaderc_limit_max_atomic_counter_bindings,
|
||||
shaderc_limit_max_vertex_atomic_counter_buffers,
|
||||
shaderc_limit_max_tess_control_atomic_counter_buffers,
|
||||
shaderc_limit_max_tess_evaluation_atomic_counter_buffers,
|
||||
shaderc_limit_max_geometry_atomic_counter_buffers,
|
||||
shaderc_limit_max_fragment_atomic_counter_buffers,
|
||||
shaderc_limit_max_combined_atomic_counter_buffers,
|
||||
shaderc_limit_max_atomic_counter_buffer_size,
|
||||
shaderc_limit_max_transform_feedback_buffers,
|
||||
shaderc_limit_max_transform_feedback_interleaved_components,
|
||||
shaderc_limit_max_cull_distances,
|
||||
shaderc_limit_max_combined_clip_and_cull_distances,
|
||||
shaderc_limit_max_samples,
|
||||
shaderc_limit_max_mesh_output_vertices_nv,
|
||||
shaderc_limit_max_mesh_output_primitives_nv,
|
||||
shaderc_limit_max_mesh_work_group_size_x_nv,
|
||||
shaderc_limit_max_mesh_work_group_size_y_nv,
|
||||
shaderc_limit_max_mesh_work_group_size_z_nv,
|
||||
shaderc_limit_max_task_work_group_size_x_nv,
|
||||
shaderc_limit_max_task_work_group_size_y_nv,
|
||||
shaderc_limit_max_task_work_group_size_z_nv,
|
||||
shaderc_limit_max_mesh_view_count_nv,
|
||||
shaderc_limit_max_mesh_output_vertices_ext,
|
||||
shaderc_limit_max_mesh_output_primitives_ext,
|
||||
shaderc_limit_max_mesh_work_group_size_x_ext,
|
||||
shaderc_limit_max_mesh_work_group_size_y_ext,
|
||||
shaderc_limit_max_mesh_work_group_size_z_ext,
|
||||
shaderc_limit_max_task_work_group_size_x_ext,
|
||||
shaderc_limit_max_task_work_group_size_y_ext,
|
||||
shaderc_limit_max_task_work_group_size_z_ext,
|
||||
shaderc_limit_max_mesh_view_count_ext,
|
||||
shaderc_limit_max_dual_source_draw_buffers_ext,
|
||||
} shaderc_limit;
|
||||
|
||||
// Uniform resource kinds.
|
||||
// In Vulkan, uniform resources are bound to the pipeline via descriptors
|
||||
// with numbered bindings and sets.
|
||||
typedef enum {
|
||||
// Image and image buffer.
|
||||
shaderc_uniform_kind_image,
|
||||
// Pure sampler.
|
||||
shaderc_uniform_kind_sampler,
|
||||
// Sampled texture in GLSL, and Shader Resource View in HLSL.
|
||||
shaderc_uniform_kind_texture,
|
||||
// Uniform Buffer Object (UBO) in GLSL. Cbuffer in HLSL.
|
||||
shaderc_uniform_kind_buffer,
|
||||
// Shader Storage Buffer Object (SSBO) in GLSL.
|
||||
shaderc_uniform_kind_storage_buffer,
|
||||
// Unordered Access View, in HLSL. (Writable storage image or storage
|
||||
// buffer.)
|
||||
shaderc_uniform_kind_unordered_access_view,
|
||||
} shaderc_uniform_kind;
|
||||
|
||||
// Usage examples:
|
||||
//
|
||||
// Aggressively release compiler resources, but spend time in initialization
|
||||
// for each new use.
|
||||
// shaderc_compiler_t compiler = shaderc_compiler_initialize();
|
||||
// shaderc_compilation_result_t result = shaderc_compile_into_spv(
|
||||
// compiler, "#version 450\nvoid main() {}", 27,
|
||||
// shaderc_glsl_vertex_shader, "main.vert", "main", nullptr);
|
||||
// // Do stuff with compilation results.
|
||||
// shaderc_result_release(result);
|
||||
// shaderc_compiler_release(compiler);
|
||||
//
|
||||
// Keep the compiler object around for a long time, but pay for extra space
|
||||
// occupied.
|
||||
// shaderc_compiler_t compiler = shaderc_compiler_initialize();
|
||||
// // On the same, other or multiple simultaneous threads.
|
||||
// shaderc_compilation_result_t result = shaderc_compile_into_spv(
|
||||
// compiler, "#version 450\nvoid main() {}", 27,
|
||||
// shaderc_glsl_vertex_shader, "main.vert", "main", nullptr);
|
||||
// // Do stuff with compilation results.
|
||||
// shaderc_result_release(result);
|
||||
// // Once no more compilations are to happen.
|
||||
// shaderc_compiler_release(compiler);
|
||||
|
||||
// An opaque handle to an object that manages all compiler state.
|
||||
typedef struct shaderc_compiler* shaderc_compiler_t;
|
||||
|
||||
// Returns a shaderc_compiler_t that can be used to compile modules.
|
||||
// A return of NULL indicates that there was an error initializing the compiler.
|
||||
// Any function operating on shaderc_compiler_t must offer the basic
|
||||
// thread-safety guarantee.
|
||||
// [http://herbsutter.com/2014/01/13/gotw-95-solution-thread-safety-and-synchronization/]
|
||||
// That is: concurrent invocation of these functions on DIFFERENT objects needs
|
||||
// no synchronization; concurrent invocation of these functions on the SAME
|
||||
// object requires synchronization IF AND ONLY IF some of them take a non-const
|
||||
// argument.
|
||||
SHADERC_EXPORT shaderc_compiler_t shaderc_compiler_initialize(void);
|
||||
|
||||
// Releases the resources held by the shaderc_compiler_t.
|
||||
// After this call it is invalid to make any future calls to functions
|
||||
// involving this shaderc_compiler_t.
|
||||
SHADERC_EXPORT void shaderc_compiler_release(shaderc_compiler_t);
|
||||
|
||||
// An opaque handle to an object that manages options to a single compilation
|
||||
// result.
|
||||
typedef struct shaderc_compile_options* shaderc_compile_options_t;
|
||||
|
||||
// Returns a default-initialized shaderc_compile_options_t that can be used
|
||||
// to modify the functionality of a compiled module.
|
||||
// A return of NULL indicates that there was an error initializing the options.
|
||||
// Any function operating on shaderc_compile_options_t must offer the
|
||||
// basic thread-safety guarantee.
|
||||
SHADERC_EXPORT shaderc_compile_options_t
|
||||
shaderc_compile_options_initialize(void);
|
||||
|
||||
// Returns a copy of the given shaderc_compile_options_t.
|
||||
// If NULL is passed as the parameter the call is the same as
|
||||
// shaderc_compile_options_init.
|
||||
SHADERC_EXPORT shaderc_compile_options_t shaderc_compile_options_clone(
|
||||
const shaderc_compile_options_t options);
|
||||
|
||||
// Releases the compilation options. It is invalid to use the given
|
||||
// shaderc_compile_options_t object in any future calls. It is safe to pass
|
||||
// NULL to this function, and doing such will have no effect.
|
||||
SHADERC_EXPORT void shaderc_compile_options_release(
|
||||
shaderc_compile_options_t options);
|
||||
|
||||
// Adds a predefined macro to the compilation options. This has the same
|
||||
// effect as passing -Dname=value to the command-line compiler. If value
|
||||
// is NULL, it has the same effect as passing -Dname to the command-line
|
||||
// compiler. If a macro definition with the same name has previously been
|
||||
// added, the value is replaced with the new value. The macro name and
|
||||
// value are passed in with char pointers, which point to their data, and
|
||||
// the lengths of their data. The strings that the name and value pointers
|
||||
// point to must remain valid for the duration of the call, but can be
|
||||
// modified or deleted after this function has returned. In case of adding
|
||||
// a valueless macro, the value argument should be a null pointer or the
|
||||
// value_length should be 0u.
|
||||
SHADERC_EXPORT void shaderc_compile_options_add_macro_definition(
|
||||
shaderc_compile_options_t options, const char* name, size_t name_length,
|
||||
const char* value, size_t value_length);
|
||||
|
||||
// Sets the source language. The default is GLSL.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_source_language(
|
||||
shaderc_compile_options_t options, shaderc_source_language lang);
|
||||
|
||||
// Sets the compiler mode to generate debug information in the output.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_generate_debug_info(
|
||||
shaderc_compile_options_t options);
|
||||
|
||||
// Sets the compiler optimization level to the given level. Only the last one
|
||||
// takes effect if multiple calls of this function exist.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_optimization_level(
|
||||
shaderc_compile_options_t options, shaderc_optimization_level level);
|
||||
|
||||
// Forces the GLSL language version and profile to a given pair. The version
|
||||
// number is the same as would appear in the #version annotation in the source.
|
||||
// Version and profile specified here overrides the #version annotation in the
|
||||
// source. Use profile: 'shaderc_profile_none' for GLSL versions that do not
|
||||
// define profiles, e.g. versions below 150.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_forced_version_profile(
|
||||
shaderc_compile_options_t options, int version, shaderc_profile profile);
|
||||
|
||||
// Source text inclusion via #include is supported with a pair of callbacks
|
||||
// to an "includer" on the client side. The first callback processes an
|
||||
// inclusion request, and returns an include result. The includer owns
|
||||
// the contents of the result, and those contents must remain valid until the
|
||||
// second callback is invoked to release the result. Both callbacks take a
|
||||
// user_data argument to specify the client context.
|
||||
// To return an error, set the source_name to an empty string and put your
|
||||
// error message in content.
|
||||
|
||||
// An include result.
|
||||
typedef struct shaderc_include_result {
|
||||
// The name of the source file. The name should be fully resolved
|
||||
// in the sense that it should be a unique name in the context of the
|
||||
// includer. For example, if the includer maps source names to files in
|
||||
// a filesystem, then this name should be the absolute path of the file.
|
||||
// For a failed inclusion, this string is empty.
|
||||
const char* source_name;
|
||||
size_t source_name_length;
|
||||
// The text contents of the source file in the normal case.
|
||||
// For a failed inclusion, this contains the error message.
|
||||
const char* content;
|
||||
size_t content_length;
|
||||
// User data to be passed along with this request.
|
||||
void* user_data;
|
||||
} shaderc_include_result;
|
||||
|
||||
// The kinds of include requests.
|
||||
enum shaderc_include_type {
|
||||
shaderc_include_type_relative, // E.g. #include "source"
|
||||
shaderc_include_type_standard // E.g. #include <source>
|
||||
};
|
||||
|
||||
// An includer callback type for mapping an #include request to an include
|
||||
// result. The user_data parameter specifies the client context. The
|
||||
// requested_source parameter specifies the name of the source being requested.
|
||||
// The type parameter specifies the kind of inclusion request being made.
|
||||
// The requesting_source parameter specifies the name of the source containing
|
||||
// the #include request. The includer owns the result object and its contents,
|
||||
// and both must remain valid until the release callback is called on the result
|
||||
// object.
|
||||
typedef shaderc_include_result* (*shaderc_include_resolve_fn)(
|
||||
void* user_data, const char* requested_source, int type,
|
||||
const char* requesting_source, size_t include_depth);
|
||||
|
||||
// An includer callback type for destroying an include result.
|
||||
typedef void (*shaderc_include_result_release_fn)(
|
||||
void* user_data, shaderc_include_result* include_result);
|
||||
|
||||
// Sets includer callback functions.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_include_callbacks(
|
||||
shaderc_compile_options_t options, shaderc_include_resolve_fn resolver,
|
||||
shaderc_include_result_release_fn result_releaser, void* user_data);
|
||||
|
||||
// Sets the compiler mode to suppress warnings, overriding warnings-as-errors
|
||||
// mode. When both suppress-warnings and warnings-as-errors modes are
|
||||
// turned on, warning messages will be inhibited, and will not be emitted
|
||||
// as error messages.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_suppress_warnings(
|
||||
shaderc_compile_options_t options);
|
||||
|
||||
// Sets the target shader environment, affecting which warnings or errors will
|
||||
// be issued. The version will be for distinguishing between different versions
|
||||
// of the target environment. The version value should be either 0 or
|
||||
// a value listed in shaderc_env_version. The 0 value maps to Vulkan 1.0 if
|
||||
// |target| is Vulkan, and it maps to OpenGL 4.5 if |target| is OpenGL.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_target_env(
|
||||
shaderc_compile_options_t options,
|
||||
shaderc_target_env target,
|
||||
uint32_t version);
|
||||
|
||||
// Sets the target SPIR-V version. The generated module will use this version
|
||||
// of SPIR-V. Each target environment determines what versions of SPIR-V
|
||||
// it can consume. Defaults to the highest version of SPIR-V 1.0 which is
|
||||
// required to be supported by the target environment. E.g. Default to SPIR-V
|
||||
// 1.0 for Vulkan 1.0 and SPIR-V 1.3 for Vulkan 1.1.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_target_spirv(
|
||||
shaderc_compile_options_t options, shaderc_spirv_version version);
|
||||
|
||||
// Sets the compiler mode to treat all warnings as errors. Note the
|
||||
// suppress-warnings mode overrides this option, i.e. if both
|
||||
// warning-as-errors and suppress-warnings modes are set, warnings will not
|
||||
// be emitted as error messages.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_warnings_as_errors(
|
||||
shaderc_compile_options_t options);
|
||||
|
||||
// Sets a resource limit.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_limit(
|
||||
shaderc_compile_options_t options, shaderc_limit limit, int value);
|
||||
|
||||
// Sets whether the compiler should automatically assign bindings to uniforms
|
||||
// that aren't already explicitly bound in the shader source.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_auto_bind_uniforms(
|
||||
shaderc_compile_options_t options, bool auto_bind);
|
||||
|
||||
// Sets whether the compiler should automatically remove sampler variables
|
||||
// and convert image variables to combined image-sampler variables.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_auto_combined_image_sampler(
|
||||
shaderc_compile_options_t options, bool upgrade);
|
||||
|
||||
// Sets whether the compiler should use HLSL IO mapping rules for bindings.
|
||||
// Defaults to false.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_hlsl_io_mapping(
|
||||
shaderc_compile_options_t options, bool hlsl_iomap);
|
||||
|
||||
// Sets whether the compiler should determine block member offsets using HLSL
|
||||
// packing rules instead of standard GLSL rules. Defaults to false. Only
|
||||
// affects GLSL compilation. HLSL rules are always used when compiling HLSL.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_hlsl_offsets(
|
||||
shaderc_compile_options_t options, bool hlsl_offsets);
|
||||
|
||||
// Sets the base binding number used for for a uniform resource type when
|
||||
// automatically assigning bindings. For GLSL compilation, sets the lowest
|
||||
// automatically assigned number. For HLSL compilation, the regsiter number
|
||||
// assigned to the resource is added to this specified base.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_binding_base(
|
||||
shaderc_compile_options_t options,
|
||||
shaderc_uniform_kind kind,
|
||||
uint32_t base);
|
||||
|
||||
// Like shaderc_compile_options_set_binding_base, but only takes effect when
|
||||
// compiling a given shader stage. The stage is assumed to be one of vertex,
|
||||
// fragment, tessellation evaluation, tesselation control, geometry, or compute.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_binding_base_for_stage(
|
||||
shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
|
||||
shaderc_uniform_kind kind, uint32_t base);
|
||||
|
||||
// Sets whether the compiler should preserve all bindings, even when those
|
||||
// bindings are not used.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_preserve_bindings(
|
||||
shaderc_compile_options_t options, bool preserve_bindings);
|
||||
|
||||
// Sets whether the compiler should automatically assign locations to
|
||||
// uniform variables that don't have explicit locations in the shader source.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_auto_map_locations(
|
||||
shaderc_compile_options_t options, bool auto_map);
|
||||
|
||||
// Sets a descriptor set and binding for an HLSL register in the given stage.
|
||||
// This method keeps a copy of the string data.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
|
||||
shaderc_compile_options_t options, shaderc_shader_kind shader_kind,
|
||||
const char* reg, const char* set, const char* binding);
|
||||
|
||||
// Like shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage,
|
||||
// but affects all shader stages.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_hlsl_register_set_and_binding(
|
||||
shaderc_compile_options_t options, const char* reg, const char* set,
|
||||
const char* binding);
|
||||
|
||||
// Sets whether the compiler should enable extension
|
||||
// SPV_GOOGLE_hlsl_functionality1.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_hlsl_functionality1(
|
||||
shaderc_compile_options_t options, bool enable);
|
||||
|
||||
// Sets whether 16-bit types are supported in HLSL or not.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_hlsl_16bit_types(
|
||||
shaderc_compile_options_t options, bool enable);
|
||||
|
||||
// Enables or disables relaxed Vulkan rules.
|
||||
//
|
||||
// This allows most OpenGL shaders to compile under Vulkan semantics.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_vulkan_rules_relaxed(
|
||||
shaderc_compile_options_t options, bool enable);
|
||||
|
||||
// Sets whether the compiler should invert position.Y output in vertex shader.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_invert_y(
|
||||
shaderc_compile_options_t options, bool enable);
|
||||
|
||||
// Sets whether the compiler generates code for max and min builtins which,
|
||||
// if given a NaN operand, will return the other operand. Similarly, the clamp
|
||||
// builtin will favour the non-NaN operands, as if clamp were implemented
|
||||
// as a composition of max and min.
|
||||
SHADERC_EXPORT void shaderc_compile_options_set_nan_clamp(
|
||||
shaderc_compile_options_t options, bool enable);
|
||||
|
||||
// An opaque handle to the results of a call to any shaderc_compile_into_*()
|
||||
// function.
|
||||
typedef struct shaderc_compilation_result* shaderc_compilation_result_t;
|
||||
|
||||
// Takes a GLSL source string and the associated shader kind, input file
|
||||
// name, compiles it according to the given additional_options. If the shader
|
||||
// kind is not set to a specified kind, but shaderc_glslc_infer_from_source,
|
||||
// the compiler will try to deduce the shader kind from the source
|
||||
// string and a failure in deducing will generate an error. Currently only
|
||||
// #pragma annotation is supported. If the shader kind is set to one of the
|
||||
// default shader kinds, the compiler will fall back to the default shader
|
||||
// kind in case it failed to deduce the shader kind from source string.
|
||||
// The input_file_name is a null-termintated string. It is used as a tag to
|
||||
// identify the source string in cases like emitting error messages. It
|
||||
// doesn't have to be a 'file name'.
|
||||
// The source string will be compiled into SPIR-V binary and a
|
||||
// shaderc_compilation_result will be returned to hold the results.
|
||||
// The entry_point_name null-terminated string defines the name of the entry
|
||||
// point to associate with this GLSL source. If the additional_options
|
||||
// parameter is not null, then the compilation is modified by any options
|
||||
// present. May be safely called from multiple threads without explicit
|
||||
// synchronization. If there was failure in allocating the compiler object,
|
||||
// null will be returned.
|
||||
SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
const shaderc_compile_options_t additional_options);
|
||||
|
||||
// Like shaderc_compile_into_spv, but the result contains SPIR-V assembly text
|
||||
// instead of a SPIR-V binary module. The SPIR-V assembly syntax is as defined
|
||||
// by the SPIRV-Tools open source project.
|
||||
SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
const shaderc_compile_options_t additional_options);
|
||||
|
||||
// Like shaderc_compile_into_spv, but the result contains preprocessed source
|
||||
// code instead of a SPIR-V binary module
|
||||
SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
|
||||
const shaderc_compiler_t compiler, const char* source_text,
|
||||
size_t source_text_size, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
const shaderc_compile_options_t additional_options);
|
||||
|
||||
// Takes an assembly string of the format defined in the SPIRV-Tools project
|
||||
// (https://github.com/KhronosGroup/SPIRV-Tools/blob/master/syntax.md),
|
||||
// assembles it into SPIR-V binary and a shaderc_compilation_result will be
|
||||
// returned to hold the results.
|
||||
// The assembling will pick options suitable for assembling specified in the
|
||||
// additional_options parameter.
|
||||
// May be safely called from multiple threads without explicit synchronization.
|
||||
// If there was failure in allocating the compiler object, null will be
|
||||
// returned.
|
||||
SHADERC_EXPORT shaderc_compilation_result_t shaderc_assemble_into_spv(
|
||||
const shaderc_compiler_t compiler, const char* source_assembly,
|
||||
size_t source_assembly_size,
|
||||
const shaderc_compile_options_t additional_options);
|
||||
|
||||
// The following functions, operating on shaderc_compilation_result_t objects,
|
||||
// offer only the basic thread-safety guarantee.
|
||||
|
||||
// Releases the resources held by the result object. It is invalid to use the
|
||||
// result object for any further operations.
|
||||
SHADERC_EXPORT void shaderc_result_release(shaderc_compilation_result_t result);
|
||||
|
||||
// Returns the number of bytes of the compilation output data in a result
|
||||
// object.
|
||||
SHADERC_EXPORT size_t shaderc_result_get_length(const shaderc_compilation_result_t result);
|
||||
|
||||
// Returns the number of warnings generated during the compilation.
|
||||
SHADERC_EXPORT size_t shaderc_result_get_num_warnings(
|
||||
const shaderc_compilation_result_t result);
|
||||
|
||||
// Returns the number of errors generated during the compilation.
|
||||
SHADERC_EXPORT size_t shaderc_result_get_num_errors(const shaderc_compilation_result_t result);
|
||||
|
||||
// Returns the compilation status, indicating whether the compilation succeeded,
|
||||
// or failed due to some reasons, like invalid shader stage or compilation
|
||||
// errors.
|
||||
SHADERC_EXPORT shaderc_compilation_status shaderc_result_get_compilation_status(
|
||||
const shaderc_compilation_result_t);
|
||||
|
||||
// Returns a pointer to the start of the compilation output data bytes, either
|
||||
// SPIR-V binary or char string. When the source string is compiled into SPIR-V
|
||||
// binary, this is guaranteed to be castable to a uint32_t*. If the result
|
||||
// contains assembly text or preprocessed source text, the pointer will point to
|
||||
// the resulting array of characters.
|
||||
SHADERC_EXPORT const char* shaderc_result_get_bytes(const shaderc_compilation_result_t result);
|
||||
|
||||
// Returns a null-terminated string that contains any error messages generated
|
||||
// during the compilation.
|
||||
SHADERC_EXPORT const char* shaderc_result_get_error_message(
|
||||
const shaderc_compilation_result_t result);
|
||||
|
||||
// Provides the version & revision of the SPIR-V which will be produced
|
||||
SHADERC_EXPORT void shaderc_get_spv_version(unsigned int* version, unsigned int* revision);
|
||||
|
||||
// Parses the version and profile from a given null-terminated string
|
||||
// containing both version and profile, like: '450core'. Returns false if
|
||||
// the string can not be parsed. Returns true when the parsing succeeds. The
|
||||
// parsed version and profile are returned through arguments.
|
||||
SHADERC_EXPORT bool shaderc_parse_version_profile(const char* str, int* version,
|
||||
shaderc_profile* profile);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // SHADERC_SHADERC_H_
|
||||
@ -0,0 +1,620 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SHADERC_SHADERC_HPP_
|
||||
#define SHADERC_SHADERC_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "shaderc.h"
|
||||
|
||||
namespace shaderc {
|
||||
// A CompilationResult contains the compiler output, compilation status,
|
||||
// and messages.
|
||||
//
|
||||
// The compiler output is stored as an array of elements and accessed
|
||||
// via random access iterators provided by cbegin() and cend(). The iterators
|
||||
// are contiguous in the sense of "Contiguous Iterators: A Refinement of
|
||||
// Random Access Iterators", Nevin Liber, C++ Library Evolution Working
|
||||
// Group Working Paper N3884.
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3884.pdf
|
||||
//
|
||||
// Methods begin() and end() are also provided to enable range-based for.
|
||||
// They are synonyms to cbegin() and cend(), respectively.
|
||||
template <typename OutputElementType>
|
||||
class CompilationResult {
|
||||
public:
|
||||
typedef OutputElementType element_type;
|
||||
// The type used to describe the begin and end iterators on the
|
||||
// compiler output.
|
||||
typedef const OutputElementType* const_iterator;
|
||||
|
||||
// Upon creation, the CompilationResult takes ownership of the
|
||||
// shaderc_compilation_result instance. During destruction of the
|
||||
// CompilationResult, the shaderc_compilation_result will be released.
|
||||
explicit CompilationResult(shaderc_compilation_result_t compilation_result)
|
||||
: compilation_result_(compilation_result) {}
|
||||
CompilationResult() : compilation_result_(nullptr) {}
|
||||
~CompilationResult() { shaderc_result_release(compilation_result_); }
|
||||
|
||||
CompilationResult(CompilationResult&& other) : compilation_result_(nullptr) {
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
CompilationResult& operator=(CompilationResult&& other) {
|
||||
if (compilation_result_) {
|
||||
shaderc_result_release(compilation_result_);
|
||||
}
|
||||
compilation_result_ = other.compilation_result_;
|
||||
other.compilation_result_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Returns any error message found during compilation.
|
||||
std::string GetErrorMessage() const {
|
||||
if (!compilation_result_) {
|
||||
return "";
|
||||
}
|
||||
return shaderc_result_get_error_message(compilation_result_);
|
||||
}
|
||||
|
||||
// Returns the compilation status, indicating whether the compilation
|
||||
// succeeded, or failed due to some reasons, like invalid shader stage or
|
||||
// compilation errors.
|
||||
shaderc_compilation_status GetCompilationStatus() const {
|
||||
if (!compilation_result_) {
|
||||
return shaderc_compilation_status_null_result_object;
|
||||
}
|
||||
return shaderc_result_get_compilation_status(compilation_result_);
|
||||
}
|
||||
|
||||
// Returns a random access (contiguous) iterator pointing to the start
|
||||
// of the compilation output. It is valid for the lifetime of this object.
|
||||
// If there is no compilation result, then returns nullptr.
|
||||
const_iterator cbegin() const {
|
||||
if (!compilation_result_) return nullptr;
|
||||
return reinterpret_cast<const_iterator>(
|
||||
shaderc_result_get_bytes(compilation_result_));
|
||||
}
|
||||
|
||||
// Returns a random access (contiguous) iterator pointing to the end of
|
||||
// the compilation output. It is valid for the lifetime of this object.
|
||||
// If there is no compilation result, then returns nullptr.
|
||||
const_iterator cend() const {
|
||||
if (!compilation_result_) return nullptr;
|
||||
return cbegin() +
|
||||
shaderc_result_get_length(compilation_result_) /
|
||||
sizeof(OutputElementType);
|
||||
}
|
||||
|
||||
// Returns the same iterator as cbegin().
|
||||
const_iterator begin() const { return cbegin(); }
|
||||
// Returns the same iterator as cend().
|
||||
const_iterator end() const { return cend(); }
|
||||
|
||||
// Returns the number of warnings generated during the compilation.
|
||||
size_t GetNumWarnings() const {
|
||||
if (!compilation_result_) {
|
||||
return 0;
|
||||
}
|
||||
return shaderc_result_get_num_warnings(compilation_result_);
|
||||
}
|
||||
|
||||
// Returns the number of errors generated during the compilation.
|
||||
size_t GetNumErrors() const {
|
||||
if (!compilation_result_) {
|
||||
return 0;
|
||||
}
|
||||
return shaderc_result_get_num_errors(compilation_result_);
|
||||
}
|
||||
|
||||
private:
|
||||
CompilationResult(const CompilationResult& other) = delete;
|
||||
CompilationResult& operator=(const CompilationResult& other) = delete;
|
||||
|
||||
shaderc_compilation_result_t compilation_result_;
|
||||
};
|
||||
|
||||
// A compilation result for a SPIR-V binary module, which is an array
|
||||
// of uint32_t words.
|
||||
using SpvCompilationResult = CompilationResult<uint32_t>;
|
||||
// A compilation result in SPIR-V assembly syntax.
|
||||
using AssemblyCompilationResult = CompilationResult<char>;
|
||||
// Preprocessed source text.
|
||||
using PreprocessedSourceCompilationResult = CompilationResult<char>;
|
||||
|
||||
// Contains any options that can have default values for a compilation.
|
||||
class CompileOptions {
|
||||
public:
|
||||
CompileOptions() { options_ = shaderc_compile_options_initialize(); }
|
||||
~CompileOptions() { shaderc_compile_options_release(options_); }
|
||||
CompileOptions(const CompileOptions& other) {
|
||||
options_ = shaderc_compile_options_clone(other.options_);
|
||||
}
|
||||
CompileOptions(CompileOptions&& other) {
|
||||
options_ = other.options_;
|
||||
other.options_ = nullptr;
|
||||
}
|
||||
|
||||
// Adds a predefined macro to the compilation options. It behaves the same as
|
||||
// shaderc_compile_options_add_macro_definition in shaderc.h.
|
||||
void AddMacroDefinition(const char* name, size_t name_length,
|
||||
const char* value, size_t value_length) {
|
||||
shaderc_compile_options_add_macro_definition(options_, name, name_length,
|
||||
value, value_length);
|
||||
}
|
||||
|
||||
// Adds a valueless predefined macro to the compilation options.
|
||||
void AddMacroDefinition(const std::string& name) {
|
||||
AddMacroDefinition(name.c_str(), name.size(), nullptr, 0u);
|
||||
}
|
||||
|
||||
// Adds a predefined macro to the compilation options.
|
||||
void AddMacroDefinition(const std::string& name, const std::string& value) {
|
||||
AddMacroDefinition(name.c_str(), name.size(), value.c_str(), value.size());
|
||||
}
|
||||
|
||||
// Sets the compiler mode to generate debug information in the output.
|
||||
void SetGenerateDebugInfo() {
|
||||
shaderc_compile_options_set_generate_debug_info(options_);
|
||||
}
|
||||
|
||||
// Sets the compiler optimization level to the given level. Only the last one
|
||||
// takes effect if multiple calls of this function exist.
|
||||
void SetOptimizationLevel(shaderc_optimization_level level) {
|
||||
shaderc_compile_options_set_optimization_level(options_, level);
|
||||
}
|
||||
|
||||
// A C++ version of the libshaderc includer interface.
|
||||
class IncluderInterface {
|
||||
public:
|
||||
// Handles shaderc_include_resolver_fn callbacks.
|
||||
virtual shaderc_include_result* GetInclude(const char* requested_source,
|
||||
shaderc_include_type type,
|
||||
const char* requesting_source,
|
||||
size_t include_depth) = 0;
|
||||
|
||||
// Handles shaderc_include_result_release_fn callbacks.
|
||||
virtual void ReleaseInclude(shaderc_include_result* data) = 0;
|
||||
|
||||
virtual ~IncluderInterface() = default;
|
||||
};
|
||||
|
||||
// Sets the includer instance for libshaderc to call during compilation, as
|
||||
// described in shaderc_compile_options_set_include_callbacks(). Callbacks
|
||||
// are routed to this includer's methods.
|
||||
void SetIncluder(std::unique_ptr<IncluderInterface>&& includer) {
|
||||
includer_ = std::move(includer);
|
||||
shaderc_compile_options_set_include_callbacks(
|
||||
options_,
|
||||
[](void* user_data, const char* requested_source, int type,
|
||||
const char* requesting_source, size_t include_depth) {
|
||||
auto* sub_includer = static_cast<IncluderInterface*>(user_data);
|
||||
return sub_includer->GetInclude(
|
||||
requested_source, static_cast<shaderc_include_type>(type),
|
||||
requesting_source, include_depth);
|
||||
},
|
||||
[](void* user_data, shaderc_include_result* include_result) {
|
||||
auto* sub_includer = static_cast<IncluderInterface*>(user_data);
|
||||
return sub_includer->ReleaseInclude(include_result);
|
||||
},
|
||||
includer_.get());
|
||||
}
|
||||
|
||||
// Forces the GLSL language version and profile to a given pair. The version
|
||||
// number is the same as would appear in the #version annotation in the
|
||||
// source. Version and profile specified here overrides the #version
|
||||
// annotation in the source. Use profile: 'shaderc_profile_none' for GLSL
|
||||
// versions that do not define profiles, e.g. versions below 150.
|
||||
void SetForcedVersionProfile(int version, shaderc_profile profile) {
|
||||
shaderc_compile_options_set_forced_version_profile(options_, version,
|
||||
profile);
|
||||
}
|
||||
|
||||
// Sets the compiler mode to suppress warnings. Note this option overrides
|
||||
// warnings-as-errors mode. When both suppress-warnings and warnings-as-errors
|
||||
// modes are turned on, warning messages will be inhibited, and will not be
|
||||
// emitted as error message.
|
||||
void SetSuppressWarnings() {
|
||||
shaderc_compile_options_set_suppress_warnings(options_);
|
||||
}
|
||||
|
||||
// Sets the source language. The default is GLSL.
|
||||
void SetSourceLanguage(shaderc_source_language lang) {
|
||||
shaderc_compile_options_set_source_language(options_, lang);
|
||||
}
|
||||
|
||||
// Sets the target shader environment, affecting which warnings or errors will
|
||||
// be issued. The version will be for distinguishing between different
|
||||
// versions of the target environment. The version value should be either 0
|
||||
// or a value listed in shaderc_env_version. The 0 value maps to Vulkan 1.0
|
||||
// if |target| is Vulkan, and it maps to OpenGL 4.5 if |target| is OpenGL.
|
||||
void SetTargetEnvironment(shaderc_target_env target, uint32_t version) {
|
||||
shaderc_compile_options_set_target_env(options_, target, version);
|
||||
}
|
||||
|
||||
// Sets the target SPIR-V version. The generated module will use this version
|
||||
// of SPIR-V. Each target environment determines what versions of SPIR-V
|
||||
// it can consume. Defaults to the highest version of SPIR-V 1.0 which is
|
||||
// required to be supported by the target environment. E.g. Default to SPIR-V
|
||||
// 1.0 for Vulkan 1.0 and SPIR-V 1.3 for Vulkan 1.1.
|
||||
void SetTargetSpirv(shaderc_spirv_version version) {
|
||||
shaderc_compile_options_set_target_spirv(options_, version);
|
||||
}
|
||||
|
||||
// Sets the compiler mode to make all warnings into errors. Note the
|
||||
// suppress-warnings mode overrides this option, i.e. if both
|
||||
// warning-as-errors and suppress-warnings modes are set on, warnings will not
|
||||
// be emitted as error message.
|
||||
void SetWarningsAsErrors() {
|
||||
shaderc_compile_options_set_warnings_as_errors(options_);
|
||||
}
|
||||
|
||||
// Sets a resource limit.
|
||||
void SetLimit(shaderc_limit limit, int value) {
|
||||
shaderc_compile_options_set_limit(options_, limit, value);
|
||||
}
|
||||
|
||||
// Sets whether the compiler should automatically assign bindings to uniforms
|
||||
// that aren't already explicitly bound in the shader source.
|
||||
void SetAutoBindUniforms(bool auto_bind) {
|
||||
shaderc_compile_options_set_auto_bind_uniforms(options_, auto_bind);
|
||||
}
|
||||
|
||||
// Sets whether the compiler should automatically remove sampler variables
|
||||
// and convert image variables to combined image sampler variables.
|
||||
void SetAutoSampledTextures(bool auto_sampled) {
|
||||
shaderc_compile_options_set_auto_combined_image_sampler(options_,
|
||||
auto_sampled);
|
||||
}
|
||||
|
||||
// Sets whether the compiler should use HLSL IO mapping rules for bindings.
|
||||
// Defaults to false.
|
||||
void SetHlslIoMapping(bool hlsl_iomap) {
|
||||
shaderc_compile_options_set_hlsl_io_mapping(options_, hlsl_iomap);
|
||||
}
|
||||
|
||||
// Sets whether the compiler should determine block member offsets using HLSL
|
||||
// packing rules instead of standard GLSL rules. Defaults to false. Only
|
||||
// affects GLSL compilation. HLSL rules are always used when compiling HLSL.
|
||||
void SetHlslOffsets(bool hlsl_offsets) {
|
||||
shaderc_compile_options_set_hlsl_offsets(options_, hlsl_offsets);
|
||||
}
|
||||
|
||||
// Sets the base binding number used for for a uniform resource type when
|
||||
// automatically assigning bindings. For GLSL compilation, sets the lowest
|
||||
// automatically assigned number. For HLSL compilation, the regsiter number
|
||||
// assigned to the resource is added to this specified base.
|
||||
void SetBindingBase(shaderc_uniform_kind kind, uint32_t base) {
|
||||
shaderc_compile_options_set_binding_base(options_, kind, base);
|
||||
}
|
||||
|
||||
// Like SetBindingBase, but only takes effect when compiling a given shader
|
||||
// stage. The stage is assumed to be one of vertex, fragment, tessellation
|
||||
// evaluation, tesselation control, geometry, or compute.
|
||||
void SetBindingBaseForStage(shaderc_shader_kind shader_kind,
|
||||
shaderc_uniform_kind kind, uint32_t base) {
|
||||
shaderc_compile_options_set_binding_base_for_stage(options_, shader_kind,
|
||||
kind, base);
|
||||
}
|
||||
|
||||
// Sets whether the compiler should preserve all bindings, even when those
|
||||
// bindings are not used.
|
||||
void SetPreserveBindings(bool preserve_bindings) {
|
||||
shaderc_compile_options_set_preserve_bindings(options_, preserve_bindings);
|
||||
}
|
||||
|
||||
// Sets whether the compiler automatically assigns locations to
|
||||
// uniform variables that don't have explicit locations.
|
||||
void SetAutoMapLocations(bool auto_map) {
|
||||
shaderc_compile_options_set_auto_map_locations(options_, auto_map);
|
||||
}
|
||||
|
||||
// Sets a descriptor set and binding for an HLSL register in the given stage.
|
||||
// Copies the parameter strings.
|
||||
void SetHlslRegisterSetAndBindingForStage(shaderc_shader_kind shader_kind,
|
||||
const std::string& reg,
|
||||
const std::string& set,
|
||||
const std::string& binding) {
|
||||
shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(
|
||||
options_, shader_kind, reg.c_str(), set.c_str(), binding.c_str());
|
||||
}
|
||||
|
||||
// Sets a descriptor set and binding for an HLSL register in any stage.
|
||||
// Copies the parameter strings.
|
||||
void SetHlslRegisterSetAndBinding(const std::string& reg,
|
||||
const std::string& set,
|
||||
const std::string& binding) {
|
||||
shaderc_compile_options_set_hlsl_register_set_and_binding(
|
||||
options_, reg.c_str(), set.c_str(), binding.c_str());
|
||||
}
|
||||
|
||||
// Sets whether the compiler should enable extension
|
||||
// SPV_GOOGLE_hlsl_functionality1.
|
||||
void SetHlslFunctionality1(bool enable) {
|
||||
shaderc_compile_options_set_hlsl_functionality1(options_, enable);
|
||||
}
|
||||
|
||||
// Sets whether 16-bit types are supported in HLSL or not.
|
||||
void SetHlsl16BitTypes(bool enable) {
|
||||
shaderc_compile_options_set_hlsl_16bit_types(options_, enable);
|
||||
}
|
||||
|
||||
// Enables or disables relaxed Vulkan rules.
|
||||
//
|
||||
// This allows most OpenGL shaders to compile under Vulkan semantics.
|
||||
void SetVulkanRulesRelaxed(bool enable) {
|
||||
shaderc_compile_options_set_vulkan_rules_relaxed(options_, enable);
|
||||
}
|
||||
|
||||
// Sets whether the compiler should invert position.Y output in vertex shader.
|
||||
void SetInvertY(bool enable) {
|
||||
shaderc_compile_options_set_invert_y(options_, enable);
|
||||
}
|
||||
|
||||
// Sets whether the compiler should generates code for max an min which,
|
||||
// if given a NaN operand, will return the other operand. Similarly, the
|
||||
// clamp builtin will favour the non-NaN operands, as if clamp were
|
||||
// implemented as a composition of max and min.
|
||||
void SetNanClamp(bool enable) {
|
||||
shaderc_compile_options_set_nan_clamp(options_, enable);
|
||||
}
|
||||
|
||||
private:
|
||||
CompileOptions& operator=(const CompileOptions& other) = delete;
|
||||
shaderc_compile_options_t options_;
|
||||
std::unique_ptr<IncluderInterface> includer_;
|
||||
|
||||
friend class Compiler;
|
||||
};
|
||||
|
||||
// The compilation context for compiling source to SPIR-V.
|
||||
class Compiler {
|
||||
public:
|
||||
Compiler() : compiler_(shaderc_compiler_initialize()) {}
|
||||
~Compiler() { shaderc_compiler_release(compiler_); }
|
||||
|
||||
Compiler(Compiler&& other) {
|
||||
compiler_ = other.compiler_;
|
||||
other.compiler_ = nullptr;
|
||||
}
|
||||
|
||||
bool IsValid() const { return compiler_ != nullptr; }
|
||||
|
||||
// Compiles the given source GLSL and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// The source_text parameter must be a valid pointer.
|
||||
// The source_text_size parameter must be the length of the source text.
|
||||
// The shader_kind parameter either forces the compilation to be done with a
|
||||
// specified shader kind, or hint the compiler how to determine the exact
|
||||
// shader kind. If the shader kind is set to shaderc_glslc_infer_from_source,
|
||||
// the compiler will try to deduce the shader kind from the source string and
|
||||
// a failure in this proess will generate an error. Currently only #pragma
|
||||
// annotation is supported. If the shader kind is set to one of the default
|
||||
// shader kinds, the compiler will fall back to the specified default shader
|
||||
// kind in case it failed to deduce the shader kind from the source string.
|
||||
// The input_file_name is a null-termintated string. It is used as a tag to
|
||||
// identify the source string in cases like emitting error messages. It
|
||||
// doesn't have to be a 'file name'.
|
||||
// The entry_point_name parameter is a null-terminated string specifying
|
||||
// the entry point name for HLSL compilation. For GLSL compilation, the
|
||||
// entry point name is assumed to be "main".
|
||||
// The compilation is passed any options specified in the CompileOptions
|
||||
// parameter.
|
||||
// It is valid for the returned CompilationResult object to outlive this
|
||||
// compiler object.
|
||||
// Note when the options_ has disassembly mode or preprocessing only mode set
|
||||
// on, the returned CompilationResult will hold a text string, instead of a
|
||||
// SPIR-V binary generated with default options.
|
||||
SpvCompilationResult CompileGlslToSpv(const char* source_text,
|
||||
size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name,
|
||||
const char* entry_point_name,
|
||||
const CompileOptions& options) const {
|
||||
shaderc_compilation_result_t compilation_result = shaderc_compile_into_spv(
|
||||
compiler_, source_text, source_text_size, shader_kind, input_file_name,
|
||||
entry_point_name, options.options_);
|
||||
return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Compiles the given source shader and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the first CompileGlslToSpv method but assumes the entry point name
|
||||
// is "main".
|
||||
SpvCompilationResult CompileGlslToSpv(const char* source_text,
|
||||
size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name,
|
||||
const CompileOptions& options) const {
|
||||
return CompileGlslToSpv(source_text, source_text_size, shader_kind,
|
||||
input_file_name, "main", options);
|
||||
}
|
||||
|
||||
// Compiles the given source GLSL and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the previous CompileGlslToSpv method but uses default options.
|
||||
SpvCompilationResult CompileGlslToSpv(const char* source_text,
|
||||
size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name) const {
|
||||
shaderc_compilation_result_t compilation_result =
|
||||
shaderc_compile_into_spv(compiler_, source_text, source_text_size,
|
||||
shader_kind, input_file_name, "main", nullptr);
|
||||
return SpvCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Compiles the given source shader and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the first CompileGlslToSpv method but the source is provided as
|
||||
// a std::string, and we assume the entry point is "main".
|
||||
SpvCompilationResult CompileGlslToSpv(const std::string& source_text,
|
||||
shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name,
|
||||
const CompileOptions& options) const {
|
||||
return CompileGlslToSpv(source_text.data(), source_text.size(), shader_kind,
|
||||
input_file_name, options);
|
||||
}
|
||||
|
||||
// Compiles the given source shader and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the first CompileGlslToSpv method but the source is provided as
|
||||
// a std::string.
|
||||
SpvCompilationResult CompileGlslToSpv(const std::string& source_text,
|
||||
shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name,
|
||||
const char* entry_point_name,
|
||||
const CompileOptions& options) const {
|
||||
return CompileGlslToSpv(source_text.data(), source_text.size(), shader_kind,
|
||||
input_file_name, entry_point_name, options);
|
||||
}
|
||||
|
||||
// Compiles the given source GLSL and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the previous CompileGlslToSpv method but assumes the entry point
|
||||
// name is "main".
|
||||
SpvCompilationResult CompileGlslToSpv(const std::string& source_text,
|
||||
shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name) const {
|
||||
return CompileGlslToSpv(source_text.data(), source_text.size(), shader_kind,
|
||||
input_file_name);
|
||||
}
|
||||
|
||||
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// The assembly should follow the syntax defined in the SPIRV-Tools project
|
||||
// (https://github.com/KhronosGroup/SPIRV-Tools/blob/master/syntax.md).
|
||||
// It is valid for the returned CompilationResult object to outlive this
|
||||
// compiler object.
|
||||
// The assembling will pick options suitable for assembling specified in the
|
||||
// CompileOptions parameter.
|
||||
SpvCompilationResult AssembleToSpv(const char* source_assembly,
|
||||
size_t source_assembly_size,
|
||||
const CompileOptions& options) const {
|
||||
return SpvCompilationResult(shaderc_assemble_into_spv(
|
||||
compiler_, source_assembly, source_assembly_size, options.options_));
|
||||
}
|
||||
|
||||
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the first AssembleToSpv method but uses the default compiler options.
|
||||
SpvCompilationResult AssembleToSpv(const char* source_assembly,
|
||||
size_t source_assembly_size) const {
|
||||
return SpvCompilationResult(shaderc_assemble_into_spv(
|
||||
compiler_, source_assembly, source_assembly_size, nullptr));
|
||||
}
|
||||
|
||||
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the first AssembleToSpv method but the source is provided as a
|
||||
// std::string.
|
||||
SpvCompilationResult AssembleToSpv(const std::string& source_assembly,
|
||||
const CompileOptions& options) const {
|
||||
return SpvCompilationResult(
|
||||
shaderc_assemble_into_spv(compiler_, source_assembly.data(),
|
||||
source_assembly.size(), options.options_));
|
||||
}
|
||||
|
||||
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
|
||||
// compilation result.
|
||||
// Like the first AssembleToSpv method but the source is provided as a
|
||||
// std::string and also uses default compiler options.
|
||||
SpvCompilationResult AssembleToSpv(const std::string& source_assembly) const {
|
||||
return SpvCompilationResult(shaderc_assemble_into_spv(
|
||||
compiler_, source_assembly.data(), source_assembly.size(), nullptr));
|
||||
}
|
||||
|
||||
// Compiles the given source GLSL and returns the SPIR-V assembly text
|
||||
// compilation result.
|
||||
// Options are similar to the first CompileToSpv method.
|
||||
AssemblyCompilationResult CompileGlslToSpvAssembly(
|
||||
const char* source_text, size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind, const char* input_file_name,
|
||||
const char* entry_point_name, const CompileOptions& options) const {
|
||||
shaderc_compilation_result_t compilation_result =
|
||||
shaderc_compile_into_spv_assembly(
|
||||
compiler_, source_text, source_text_size, shader_kind,
|
||||
input_file_name, entry_point_name, options.options_);
|
||||
return AssemblyCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Compiles the given source GLSL and returns the SPIR-V assembly text
|
||||
// compilation result.
|
||||
// Similare to the previous method, but assumes entry point name is "main".
|
||||
AssemblyCompilationResult CompileGlslToSpvAssembly(
|
||||
const char* source_text, size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind, const char* input_file_name,
|
||||
const CompileOptions& options) const {
|
||||
return CompileGlslToSpvAssembly(source_text, source_text_size, shader_kind,
|
||||
input_file_name, "main", options);
|
||||
}
|
||||
|
||||
// Compiles the given source GLSL and returns the SPIR-V assembly text
|
||||
// result. Like the first CompileGlslToSpvAssembly method but the source
|
||||
// is provided as a std::string. Options are otherwise similar to
|
||||
// the first CompileToSpv method.
|
||||
AssemblyCompilationResult CompileGlslToSpvAssembly(
|
||||
const std::string& source_text, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const char* entry_point_name,
|
||||
const CompileOptions& options) const {
|
||||
return CompileGlslToSpvAssembly(source_text.data(), source_text.size(),
|
||||
shader_kind, input_file_name,
|
||||
entry_point_name, options);
|
||||
}
|
||||
|
||||
// Compiles the given source GLSL and returns the SPIR-V assembly text
|
||||
// result. Like the previous CompileGlslToSpvAssembly method but assumes
|
||||
// the entry point name is "main".
|
||||
AssemblyCompilationResult CompileGlslToSpvAssembly(
|
||||
const std::string& source_text, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const CompileOptions& options) const {
|
||||
return CompileGlslToSpvAssembly(source_text, shader_kind, input_file_name,
|
||||
"main", options);
|
||||
}
|
||||
|
||||
// Preprocesses the given source GLSL and returns the preprocessed
|
||||
// source text as a compilation result.
|
||||
// Options are similar to the first CompileToSpv method.
|
||||
PreprocessedSourceCompilationResult PreprocessGlsl(
|
||||
const char* source_text, size_t source_text_size,
|
||||
shaderc_shader_kind shader_kind, const char* input_file_name,
|
||||
const CompileOptions& options) const {
|
||||
shaderc_compilation_result_t compilation_result =
|
||||
shaderc_compile_into_preprocessed_text(
|
||||
compiler_, source_text, source_text_size, shader_kind,
|
||||
input_file_name, "main", options.options_);
|
||||
return PreprocessedSourceCompilationResult(compilation_result);
|
||||
}
|
||||
|
||||
// Preprocesses the given source GLSL and returns text result. Like the first
|
||||
// PreprocessGlsl method but the source is provided as a std::string.
|
||||
// Options are otherwise similar to the first CompileToSpv method.
|
||||
PreprocessedSourceCompilationResult PreprocessGlsl(
|
||||
const std::string& source_text, shaderc_shader_kind shader_kind,
|
||||
const char* input_file_name, const CompileOptions& options) const {
|
||||
return PreprocessGlsl(source_text.data(), source_text.size(), shader_kind,
|
||||
input_file_name, options);
|
||||
}
|
||||
|
||||
private:
|
||||
Compiler(const Compiler&) = delete;
|
||||
Compiler& operator=(const Compiler& other) = delete;
|
||||
|
||||
shaderc_compiler_t compiler_;
|
||||
};
|
||||
} // namespace shaderc
|
||||
|
||||
#endif // SHADERC_SHADERC_HPP_
|
||||
@ -0,0 +1,39 @@
|
||||
// Copyright 2018 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SHADERC_STATUS_H_
|
||||
#define SHADERC_STATUS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Indicate the status of a compilation.
|
||||
typedef enum {
|
||||
shaderc_compilation_status_success = 0,
|
||||
shaderc_compilation_status_invalid_stage = 1, // error stage deduction
|
||||
shaderc_compilation_status_compilation_error = 2,
|
||||
shaderc_compilation_status_internal_error = 3, // unexpected failure
|
||||
shaderc_compilation_status_null_result_object = 4,
|
||||
shaderc_compilation_status_invalid_assembly = 5,
|
||||
shaderc_compilation_status_validation_error = 6,
|
||||
shaderc_compilation_status_transformation_error = 7,
|
||||
shaderc_compilation_status_configuration_error = 8,
|
||||
} shaderc_compilation_status;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // SHADERC_STATUS_H_
|
||||
@ -0,0 +1,37 @@
|
||||
// Copyright 2018 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SHADERC_VISIBILITY_H_
|
||||
#define SHADERC_VISIBILITY_H_
|
||||
|
||||
// SHADERC_EXPORT tags symbol that will be exposed by the shared libraries.
|
||||
#if defined(SHADERC_SHAREDLIB)
|
||||
#if defined(_WIN32)
|
||||
#if defined(SHADERC_IMPLEMENTATION)
|
||||
#define SHADERC_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define SHADERC_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#if defined(SHADERC_IMPLEMENTATION)
|
||||
#define SHADERC_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define SHADERC_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define SHADERC_EXPORT
|
||||
#endif
|
||||
|
||||
#endif // SHADERC_VISIBILITY_H_
|
||||
@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2018 The Khronos Group Inc.
|
||||
// Copyright (c) 2018 Valve Corporation
|
||||
// Copyright (c) 2018 LunarG Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
|
||||
#define INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
|
||||
|
||||
// Shader Instrumentation Interface
|
||||
//
|
||||
// This file provides an external interface for applications that wish to
|
||||
// communicate with shaders instrumented by passes created by:
|
||||
//
|
||||
// CreateInstBindlessCheckPass
|
||||
// CreateInstBuffAddrCheckPass
|
||||
// CreateInstDebugPrintfPass
|
||||
//
|
||||
// More detailed documentation of these routines can be found in optimizer.hpp
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
// Stream Output Buffer Offsets
|
||||
//
|
||||
// The following values provide offsets into the output buffer struct
|
||||
// generated by InstrumentPass::GenDebugStreamWrite. This method is utilized
|
||||
// by InstBindlessCheckPass, InstBuffAddrCheckPass, and InstDebugPrintfPass.
|
||||
//
|
||||
// The 1st member of the debug output buffer contains a set of flags
|
||||
// controlling the behavior of instrumentation code.
|
||||
static const int kDebugOutputFlagsOffset = 0;
|
||||
|
||||
// Values stored at kDebugOutputFlagsOffset
|
||||
enum kInstFlags : unsigned int {
|
||||
kInstBufferOOBEnable = 0x1,
|
||||
};
|
||||
|
||||
// The 2nd member of the debug output buffer contains the next available word
|
||||
// in the data stream to be written. Shaders will atomically read and update
|
||||
// this value so as not to overwrite each others records. This value must be
|
||||
// initialized to zero
|
||||
static const int kDebugOutputSizeOffset = 1;
|
||||
|
||||
// The 3rd member of the output buffer is the start of the stream of records
|
||||
// written by the instrumented shaders. Each record represents a validation
|
||||
// error. The format of the records is documented below.
|
||||
static const int kDebugOutputDataOffset = 2;
|
||||
|
||||
// Common Stream Record Offsets
|
||||
//
|
||||
// The following are offsets to fields which are common to all records written
|
||||
// to the output stream.
|
||||
//
|
||||
// Each record first contains the size of the record in 32-bit words, including
|
||||
// the size word.
|
||||
static const int kInstCommonOutSize = 0;
|
||||
|
||||
// This is the shader id passed by the layer when the instrumentation pass is
|
||||
// created.
|
||||
static const int kInstCommonOutShaderId = 1;
|
||||
|
||||
// This is the ordinal position of the instruction within the SPIR-V shader
|
||||
// which generated the validation error.
|
||||
static const int kInstCommonOutInstructionIdx = 2;
|
||||
|
||||
// Debug Buffer Bindings
|
||||
//
|
||||
// These are the bindings for the different buffers which are
|
||||
// read or written by the instrumentation passes.
|
||||
//
|
||||
// This is the output buffer written by InstDebugPrintfPass.
|
||||
static const int kDebugOutputPrintfStream = 3;
|
||||
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,397 @@
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_
|
||||
#define INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
// Message consumer. The C strings for source and message are only alive for the
|
||||
// specific invocation.
|
||||
using MessageConsumer = std::function<void(
|
||||
spv_message_level_t /* level */, const char* /* source */,
|
||||
const spv_position_t& /* position */, const char* /* message */
|
||||
)>;
|
||||
|
||||
using HeaderParser = std::function<spv_result_t(
|
||||
const spv_endianness_t endianess, const spv_parsed_header_t& instruction)>;
|
||||
using InstructionParser =
|
||||
std::function<spv_result_t(const spv_parsed_instruction_t& instruction)>;
|
||||
|
||||
// C++ RAII wrapper around the C context object spv_context.
|
||||
class Context {
|
||||
public:
|
||||
// Constructs a context targeting the given environment |env|.
|
||||
//
|
||||
// See specific API calls for how the target environment is interpreted
|
||||
// (particularly assembly and validation).
|
||||
//
|
||||
// The constructed instance will have an empty message consumer, which just
|
||||
// ignores all messages from the library. Use SetMessageConsumer() to supply
|
||||
// one if messages are of concern.
|
||||
explicit Context(spv_target_env env);
|
||||
|
||||
// Enables move constructor/assignment operations.
|
||||
Context(Context&& other);
|
||||
Context& operator=(Context&& other);
|
||||
|
||||
// Disables copy constructor/assignment operations.
|
||||
Context(const Context&) = delete;
|
||||
Context& operator=(const Context&) = delete;
|
||||
|
||||
// Destructs this instance.
|
||||
~Context();
|
||||
|
||||
// Sets the message consumer to the given |consumer|. The |consumer| will be
|
||||
// invoked once for each message communicated from the library.
|
||||
void SetMessageConsumer(MessageConsumer consumer);
|
||||
|
||||
// Returns the underlying spv_context.
|
||||
spv_context& CContext();
|
||||
const spv_context& CContext() const;
|
||||
|
||||
private:
|
||||
spv_context context_;
|
||||
};
|
||||
|
||||
// A RAII wrapper around a validator options object.
|
||||
class ValidatorOptions {
|
||||
public:
|
||||
ValidatorOptions() : options_(spvValidatorOptionsCreate()) {}
|
||||
~ValidatorOptions() { spvValidatorOptionsDestroy(options_); }
|
||||
// Allow implicit conversion to the underlying object.
|
||||
operator spv_validator_options() const { return options_; }
|
||||
|
||||
// Sets a limit.
|
||||
void SetUniversalLimit(spv_validator_limit limit_type, uint32_t limit) {
|
||||
spvValidatorOptionsSetUniversalLimit(options_, limit_type, limit);
|
||||
}
|
||||
|
||||
void SetRelaxStructStore(bool val) {
|
||||
spvValidatorOptionsSetRelaxStoreStruct(options_, val);
|
||||
}
|
||||
|
||||
// Enables VK_KHR_relaxed_block_layout when validating standard
|
||||
// uniform/storage buffer/push-constant layout. If true, disables
|
||||
// scalar block layout rules.
|
||||
void SetRelaxBlockLayout(bool val) {
|
||||
spvValidatorOptionsSetRelaxBlockLayout(options_, val);
|
||||
}
|
||||
|
||||
// Enables VK_KHR_uniform_buffer_standard_layout when validating standard
|
||||
// uniform layout. If true, disables scalar block layout rules.
|
||||
void SetUniformBufferStandardLayout(bool val) {
|
||||
spvValidatorOptionsSetUniformBufferStandardLayout(options_, val);
|
||||
}
|
||||
|
||||
// Enables VK_EXT_scalar_block_layout when validating standard
|
||||
// uniform/storage buffer/push-constant layout. If true, disables
|
||||
// relaxed block layout rules.
|
||||
void SetScalarBlockLayout(bool val) {
|
||||
spvValidatorOptionsSetScalarBlockLayout(options_, val);
|
||||
}
|
||||
|
||||
// Enables scalar layout when validating Workgroup blocks. See
|
||||
// VK_KHR_workgroup_memory_explicit_layout.
|
||||
void SetWorkgroupScalarBlockLayout(bool val) {
|
||||
spvValidatorOptionsSetWorkgroupScalarBlockLayout(options_, val);
|
||||
}
|
||||
|
||||
// Skips validating standard uniform/storage buffer/push-constant layout.
|
||||
void SetSkipBlockLayout(bool val) {
|
||||
spvValidatorOptionsSetSkipBlockLayout(options_, val);
|
||||
}
|
||||
|
||||
// Enables LocalSizeId decorations where the environment would not otherwise
|
||||
// allow them.
|
||||
void SetAllowLocalSizeId(bool val) {
|
||||
spvValidatorOptionsSetAllowLocalSizeId(options_, val);
|
||||
}
|
||||
|
||||
// Records whether or not the validator should relax the rules on pointer
|
||||
// usage in logical addressing mode.
|
||||
//
|
||||
// When relaxed, it will allow the following usage cases of pointers:
|
||||
// 1) OpVariable allocating an object whose type is a pointer type
|
||||
// 2) OpReturnValue returning a pointer value
|
||||
void SetRelaxLogicalPointer(bool val) {
|
||||
spvValidatorOptionsSetRelaxLogicalPointer(options_, val);
|
||||
}
|
||||
|
||||
// Records whether or not the validator should relax the rules because it is
|
||||
// expected that the optimizations will make the code legal.
|
||||
//
|
||||
// When relaxed, it will allow the following:
|
||||
// 1) It will allow relaxed logical pointers. Setting this option will also
|
||||
// set that option.
|
||||
// 2) Pointers that are pass as parameters to function calls do not have to
|
||||
// match the storage class of the formal parameter.
|
||||
// 3) Pointers that are actual parameters on function calls do not have to
|
||||
// point to the same type pointed as the formal parameter. The types just
|
||||
// need to logically match.
|
||||
// 4) GLSLstd450 Interpolate* instructions can have a load of an interpolant
|
||||
// for a first argument.
|
||||
void SetBeforeHlslLegalization(bool val) {
|
||||
spvValidatorOptionsSetBeforeHlslLegalization(options_, val);
|
||||
}
|
||||
|
||||
// Whether friendly names should be used in validation error messages.
|
||||
void SetFriendlyNames(bool val) {
|
||||
spvValidatorOptionsSetFriendlyNames(options_, val);
|
||||
}
|
||||
|
||||
private:
|
||||
spv_validator_options options_;
|
||||
};
|
||||
|
||||
// A C++ wrapper around an optimization options object.
|
||||
class OptimizerOptions {
|
||||
public:
|
||||
OptimizerOptions() : options_(spvOptimizerOptionsCreate()) {}
|
||||
~OptimizerOptions() { spvOptimizerOptionsDestroy(options_); }
|
||||
|
||||
// Allow implicit conversion to the underlying object.
|
||||
operator spv_optimizer_options() const { return options_; }
|
||||
|
||||
// Records whether or not the optimizer should run the validator before
|
||||
// optimizing. If |run| is true, the validator will be run.
|
||||
void set_run_validator(bool run) {
|
||||
spvOptimizerOptionsSetRunValidator(options_, run);
|
||||
}
|
||||
|
||||
// Records the validator options that should be passed to the validator if it
|
||||
// is run.
|
||||
void set_validator_options(const ValidatorOptions& val_options) {
|
||||
spvOptimizerOptionsSetValidatorOptions(options_, val_options);
|
||||
}
|
||||
|
||||
// Records the maximum possible value for the id bound.
|
||||
void set_max_id_bound(uint32_t new_bound) {
|
||||
spvOptimizerOptionsSetMaxIdBound(options_, new_bound);
|
||||
}
|
||||
|
||||
// Records whether all bindings within the module should be preserved.
|
||||
void set_preserve_bindings(bool preserve_bindings) {
|
||||
spvOptimizerOptionsSetPreserveBindings(options_, preserve_bindings);
|
||||
}
|
||||
|
||||
// Records whether all specialization constants within the module
|
||||
// should be preserved.
|
||||
void set_preserve_spec_constants(bool preserve_spec_constants) {
|
||||
spvOptimizerOptionsSetPreserveSpecConstants(options_,
|
||||
preserve_spec_constants);
|
||||
}
|
||||
|
||||
private:
|
||||
spv_optimizer_options options_;
|
||||
};
|
||||
|
||||
// A C++ wrapper around a reducer options object.
|
||||
class ReducerOptions {
|
||||
public:
|
||||
ReducerOptions() : options_(spvReducerOptionsCreate()) {}
|
||||
~ReducerOptions() { spvReducerOptionsDestroy(options_); }
|
||||
|
||||
// Allow implicit conversion to the underlying object.
|
||||
operator spv_reducer_options() const { // NOLINT(google-explicit-constructor)
|
||||
return options_;
|
||||
}
|
||||
|
||||
// See spvReducerOptionsSetStepLimit.
|
||||
void set_step_limit(uint32_t step_limit) {
|
||||
spvReducerOptionsSetStepLimit(options_, step_limit);
|
||||
}
|
||||
|
||||
// See spvReducerOptionsSetFailOnValidationError.
|
||||
void set_fail_on_validation_error(bool fail_on_validation_error) {
|
||||
spvReducerOptionsSetFailOnValidationError(options_,
|
||||
fail_on_validation_error);
|
||||
}
|
||||
|
||||
// See spvReducerOptionsSetTargetFunction.
|
||||
void set_target_function(uint32_t target_function) {
|
||||
spvReducerOptionsSetTargetFunction(options_, target_function);
|
||||
}
|
||||
|
||||
private:
|
||||
spv_reducer_options options_;
|
||||
};
|
||||
|
||||
// A C++ wrapper around a fuzzer options object.
|
||||
class FuzzerOptions {
|
||||
public:
|
||||
FuzzerOptions() : options_(spvFuzzerOptionsCreate()) {}
|
||||
~FuzzerOptions() { spvFuzzerOptionsDestroy(options_); }
|
||||
|
||||
// Allow implicit conversion to the underlying object.
|
||||
operator spv_fuzzer_options() const { // NOLINT(google-explicit-constructor)
|
||||
return options_;
|
||||
}
|
||||
|
||||
// See spvFuzzerOptionsEnableReplayValidation.
|
||||
void enable_replay_validation() {
|
||||
spvFuzzerOptionsEnableReplayValidation(options_);
|
||||
}
|
||||
|
||||
// See spvFuzzerOptionsSetRandomSeed.
|
||||
void set_random_seed(uint32_t seed) {
|
||||
spvFuzzerOptionsSetRandomSeed(options_, seed);
|
||||
}
|
||||
|
||||
// See spvFuzzerOptionsSetReplayRange.
|
||||
void set_replay_range(int32_t replay_range) {
|
||||
spvFuzzerOptionsSetReplayRange(options_, replay_range);
|
||||
}
|
||||
|
||||
// See spvFuzzerOptionsSetShrinkerStepLimit.
|
||||
void set_shrinker_step_limit(uint32_t shrinker_step_limit) {
|
||||
spvFuzzerOptionsSetShrinkerStepLimit(options_, shrinker_step_limit);
|
||||
}
|
||||
|
||||
// See spvFuzzerOptionsEnableFuzzerPassValidation.
|
||||
void enable_fuzzer_pass_validation() {
|
||||
spvFuzzerOptionsEnableFuzzerPassValidation(options_);
|
||||
}
|
||||
|
||||
// See spvFuzzerOptionsEnableAllPasses.
|
||||
void enable_all_passes() { spvFuzzerOptionsEnableAllPasses(options_); }
|
||||
|
||||
private:
|
||||
spv_fuzzer_options options_;
|
||||
};
|
||||
|
||||
// C++ interface for SPIRV-Tools functionalities. It wraps the context
|
||||
// (including target environment and the corresponding SPIR-V grammar) and
|
||||
// provides methods for assembling, disassembling, and validating.
|
||||
//
|
||||
// Instances of this class provide basic thread-safety guarantee.
|
||||
class SpirvTools {
|
||||
public:
|
||||
enum {
|
||||
// Default assembling option used by assemble():
|
||||
kDefaultAssembleOption = SPV_TEXT_TO_BINARY_OPTION_NONE,
|
||||
|
||||
// Default disassembling option used by Disassemble():
|
||||
// * Avoid prefix comments from decoding the SPIR-V module header, and
|
||||
// * Use friendly names for variables.
|
||||
kDefaultDisassembleOption = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
|
||||
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES
|
||||
};
|
||||
|
||||
// Constructs an instance targeting the given environment |env|.
|
||||
//
|
||||
// The constructed instance will have an empty message consumer, which just
|
||||
// ignores all messages from the library. Use SetMessageConsumer() to supply
|
||||
// one if messages are of concern.
|
||||
explicit SpirvTools(spv_target_env env);
|
||||
|
||||
// Disables copy/move constructor/assignment operations.
|
||||
SpirvTools(const SpirvTools&) = delete;
|
||||
SpirvTools(SpirvTools&&) = delete;
|
||||
SpirvTools& operator=(const SpirvTools&) = delete;
|
||||
SpirvTools& operator=(SpirvTools&&) = delete;
|
||||
|
||||
// Destructs this instance.
|
||||
~SpirvTools();
|
||||
|
||||
// Sets the message consumer to the given |consumer|. The |consumer| will be
|
||||
// invoked once for each message communicated from the library.
|
||||
void SetMessageConsumer(MessageConsumer consumer);
|
||||
|
||||
// Assembles the given assembly |text| and writes the result to |binary|.
|
||||
// Returns true on successful assembling. |binary| will be kept untouched if
|
||||
// assembling is unsuccessful.
|
||||
// The SPIR-V binary version is set to the highest version of SPIR-V supported
|
||||
// by the target environment with which this SpirvTools object was created.
|
||||
bool Assemble(const std::string& text, std::vector<uint32_t>* binary,
|
||||
uint32_t options = kDefaultAssembleOption) const;
|
||||
// |text_size| specifies the number of bytes in |text|. A terminating null
|
||||
// character is not required to present in |text| as long as |text| is valid.
|
||||
// The SPIR-V binary version is set to the highest version of SPIR-V supported
|
||||
// by the target environment with which this SpirvTools object was created.
|
||||
bool Assemble(const char* text, size_t text_size,
|
||||
std::vector<uint32_t>* binary,
|
||||
uint32_t options = kDefaultAssembleOption) const;
|
||||
|
||||
// Disassembles the given SPIR-V |binary| with the given |options| and writes
|
||||
// the assembly to |text|. Returns true on successful disassembling. |text|
|
||||
// will be kept untouched if diassembling is unsuccessful.
|
||||
bool Disassemble(const std::vector<uint32_t>& binary, std::string* text,
|
||||
uint32_t options = kDefaultDisassembleOption) const;
|
||||
// |binary_size| specifies the number of words in |binary|.
|
||||
bool Disassemble(const uint32_t* binary, size_t binary_size,
|
||||
std::string* text,
|
||||
uint32_t options = kDefaultDisassembleOption) const;
|
||||
|
||||
// Parses a SPIR-V binary, specified as counted sequence of 32-bit words.
|
||||
// Parsing feedback is provided via two callbacks provided as std::function.
|
||||
// In a valid parse the parsed-header callback is called once, and
|
||||
// then the parsed-instruction callback is called once for each instruction
|
||||
// in the stream.
|
||||
// Returns true on successful parsing.
|
||||
// If diagnostic is non-null, a diagnostic is emitted on failed parsing.
|
||||
// If diagnostic is null the context's message consumer
|
||||
// will be used to emit any errors. If a callback returns anything other than
|
||||
// SPV_SUCCESS, then that status code is returned, no further callbacks are
|
||||
// issued, and no additional diagnostics are emitted.
|
||||
// This is a wrapper around the C API spvBinaryParse.
|
||||
bool Parse(const std::vector<uint32_t>& binary,
|
||||
const HeaderParser& header_parser,
|
||||
const InstructionParser& instruction_parser,
|
||||
spv_diagnostic* diagnostic = nullptr);
|
||||
|
||||
// Validates the given SPIR-V |binary|. Returns true if no issues are found.
|
||||
// Otherwise, returns false and communicates issues via the message consumer
|
||||
// registered.
|
||||
// Validates for SPIR-V spec rules for the SPIR-V version named in the
|
||||
// binary's header (at word offset 1). Additionally, if the target
|
||||
// environment is a client API (such as Vulkan 1.1), then validate for that
|
||||
// client API version, to the extent that it is verifiable from data in the
|
||||
// binary itself.
|
||||
bool Validate(const std::vector<uint32_t>& binary) const;
|
||||
// Like the previous overload, but provides the binary as a pointer and size:
|
||||
// |binary_size| specifies the number of words in |binary|.
|
||||
// Validates for SPIR-V spec rules for the SPIR-V version named in the
|
||||
// binary's header (at word offset 1). Additionally, if the target
|
||||
// environment is a client API (such as Vulkan 1.1), then validate for that
|
||||
// client API version, to the extent that it is verifiable from data in the
|
||||
// binary itself.
|
||||
bool Validate(const uint32_t* binary, size_t binary_size) const;
|
||||
// Like the previous overload, but takes an options object.
|
||||
// Validates for SPIR-V spec rules for the SPIR-V version named in the
|
||||
// binary's header (at word offset 1). Additionally, if the target
|
||||
// environment is a client API (such as Vulkan 1.1), then validate for that
|
||||
// client API version, to the extent that it is verifiable from data in the
|
||||
// binary itself, or in the validator options.
|
||||
bool Validate(const uint32_t* binary, size_t binary_size,
|
||||
spv_validator_options options) const;
|
||||
|
||||
// Was this object successfully constructed.
|
||||
bool IsValid() const;
|
||||
|
||||
private:
|
||||
struct Impl; // Opaque struct for holding the data fields used by this class.
|
||||
std::unique_ptr<Impl> impl_; // Unique pointer to implementation data.
|
||||
};
|
||||
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_
|
||||
@ -0,0 +1,98 @@
|
||||
// Copyright (c) 2017 Pierre Moreau
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef INCLUDE_SPIRV_TOOLS_LINKER_HPP_
|
||||
#define INCLUDE_SPIRV_TOOLS_LINKER_HPP_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "libspirv.hpp"
|
||||
|
||||
namespace spvtools {
|
||||
|
||||
class LinkerOptions {
|
||||
public:
|
||||
// Returns whether a library or an executable should be produced by the
|
||||
// linking phase.
|
||||
//
|
||||
// All exported symbols are kept when creating a library, whereas they will
|
||||
// be removed when creating an executable.
|
||||
// The returned value will be true if creating a library, and false if
|
||||
// creating an executable.
|
||||
bool GetCreateLibrary() const { return create_library_; }
|
||||
|
||||
// Sets whether a library or an executable should be produced.
|
||||
void SetCreateLibrary(bool create_library) {
|
||||
create_library_ = create_library;
|
||||
}
|
||||
|
||||
// Returns whether to verify the uniqueness of the unique ids in the merged
|
||||
// context.
|
||||
bool GetVerifyIds() const { return verify_ids_; }
|
||||
|
||||
// Sets whether to verify the uniqueness of the unique ids in the merged
|
||||
// context.
|
||||
void SetVerifyIds(bool verify_ids) { verify_ids_ = verify_ids; }
|
||||
|
||||
// Returns whether to allow for imported symbols to have no corresponding
|
||||
// exported symbols
|
||||
bool GetAllowPartialLinkage() const { return allow_partial_linkage_; }
|
||||
|
||||
// Sets whether to allow for imported symbols to have no corresponding
|
||||
// exported symbols
|
||||
void SetAllowPartialLinkage(bool allow_partial_linkage) {
|
||||
allow_partial_linkage_ = allow_partial_linkage;
|
||||
}
|
||||
|
||||
bool GetUseHighestVersion() const { return use_highest_version_; }
|
||||
void SetUseHighestVersion(bool use_highest_vers) {
|
||||
use_highest_version_ = use_highest_vers;
|
||||
}
|
||||
|
||||
private:
|
||||
bool create_library_{false};
|
||||
bool verify_ids_{false};
|
||||
bool allow_partial_linkage_{false};
|
||||
bool use_highest_version_{false};
|
||||
};
|
||||
|
||||
// Links one or more SPIR-V modules into a new SPIR-V module. That is, combine
|
||||
// several SPIR-V modules into one, resolving link dependencies between them.
|
||||
//
|
||||
// At least one binary has to be provided in |binaries|. Those binaries do not
|
||||
// have to be valid, but they should be at least parseable.
|
||||
// The functions can fail due to the following:
|
||||
// * The given context was not initialised using `spvContextCreate()`;
|
||||
// * No input modules were given;
|
||||
// * One or more of those modules were not parseable;
|
||||
// * The input modules used different addressing or memory models;
|
||||
// * The ID or global variable number limit were exceeded;
|
||||
// * Some entry points were defined multiple times;
|
||||
// * Some imported symbols did not have an exported counterpart;
|
||||
// * Possibly other reasons.
|
||||
spv_result_t Link(const Context& context,
|
||||
const std::vector<std::vector<uint32_t>>& binaries,
|
||||
std::vector<uint32_t>* linked_binary,
|
||||
const LinkerOptions& options = LinkerOptions());
|
||||
spv_result_t Link(const Context& context, const uint32_t* const* binaries,
|
||||
const size_t* binary_sizes, size_t num_binaries,
|
||||
std::vector<uint32_t>* linked_binary,
|
||||
const LinkerOptions& options = LinkerOptions());
|
||||
|
||||
} // namespace spvtools
|
||||
|
||||
#endif // INCLUDE_SPIRV_TOOLS_LINKER_HPP_
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>libshaderc_combined</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.kintan.ksplayer.libshaderc.combined</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>libshaderc_combined</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>87.88.520</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>87.88.520</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>13.0</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -0,0 +1,4 @@
|
||||
framework module libshaderc_combined [system] {
|
||||
umbrella "."
|
||||
export *
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user