diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 3469b806a6e7..752d8338c735 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -660,8 +660,8 @@ void HTTPRequest::_bind_methods() { BIND_ENUM_CONSTANT(RESULT_TIMEOUT); } -HTTPRequest::HTTPRequest() { - client = Ref(HTTPClient::create()); +HTTPRequest::HTTPRequest(const Ref &p_client) { + client = (p_client == nullptr) ? Ref(HTTPClient::create()) : p_client; tls_options = TLSOptions::client(); timer = memnew(Timer); timer->set_one_shot(true); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 9a91171eafd9..30e6564d42c3 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -163,7 +163,7 @@ class HTTPRequest : public Node { void set_tls_options(const Ref &p_options); - HTTPRequest(); + HTTPRequest(const Ref &p_client = Ref()); }; VARIANT_ENUM_CAST(HTTPRequest::Result); diff --git a/tests/core/io/test_http_client_mock.h b/tests/core/io/test_http_client_mock.h new file mode 100644 index 000000000000..a786fa5660f6 --- /dev/null +++ b/tests/core/io/test_http_client_mock.h @@ -0,0 +1,95 @@ +/**************************************************************************/ +/* test_http_client_mock.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef TEST_HTTP_CLIENT_MOCK_H +#define TEST_HTTP_CLIENT_MOCK_H + +#include "core/io/http_client.h" + +class HTTPClientMock : public HTTPClient { +public: + Error request(Method p_method, const String &p_url, const Vector &p_headers, const uint8_t *p_body, int p_body_size) override { + return Error(); + } + Error connect_to_host(const String &p_host, int p_port = -1, Ref p_tls_options = Ref()) override { + return Error(); + } + + void set_connection(const Ref &p_connection) override { + } + Ref get_connection() const override { + return nullptr; + } + + void close() override { + } + + Status get_status() const override { + return Status(); + } + + bool has_response() const override { + return bool(); + } + bool is_response_chunked() const override { + return bool(); + } + int get_response_code() const override { + return int(); + } + Error get_response_headers(List *r_response) override { + return Error(); + } + int64_t get_response_body_length() const override { + return int64_t(); + } + + PackedByteArray read_response_body_chunk() override { + return PackedByteArray(); + } + + void set_blocking_mode(bool p_enable) override { + } + bool is_blocking_mode_enabled() const override { + return bool(); + } + + void set_read_chunk_size(int p_size) override { + } + int get_read_chunk_size() const override { + return int(); + } + + Error poll() override { + return Error(); + } +}; + +#endif // TEST_HTTP_CLIENT_MOCK_H diff --git a/tests/scene/test_http_request.h b/tests/scene/test_http_request.h new file mode 100644 index 000000000000..d016691d9502 --- /dev/null +++ b/tests/scene/test_http_request.h @@ -0,0 +1,61 @@ +/**************************************************************************/ +/* test_http_request.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef TEST_HTTP_REQUEST_H +#define TEST_HTTP_REQUEST_H + +#include "scene/main/http_request.h" +#include "tests/core/io/test_http_client_mock.h" +#include "tests/test_macros.h" + +#include "thirdparty/fakeit/fakeit.hpp" + +namespace TestHTTPRequest { + +TEST_CASE("[Network][HTTPRequest] Set download chunk size") { + HTTPClientMock *http_client = memnew(HTTPClientMock); + HTTPRequest *http_request = memnew(HTTPRequest(Ref(http_client))); + + fakeit::Mock *spy = new fakeit::Mock(*http_client); + fakeit::When(Method(*spy, get_status)).AlwaysReturn(HTTPClient::STATUS_DISCONNECTED); + fakeit::Spy(Method(*spy, set_read_chunk_size)); + + int expected_value = 42; + http_request->set_download_chunk_size(expected_value); + + fakeit::Verify(Method(*spy, set_read_chunk_size).Using(expected_value)); + + delete spy; + memdelete(http_request); +} + +} // namespace TestHTTPRequest + +#endif // TEST_HTTP_REQUEST_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index edadc52a1639..2c16fcb62a98 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -110,6 +110,7 @@ #include "tests/scene/test_curve_2d.h" #include "tests/scene/test_curve_3d.h" #include "tests/scene/test_gradient.h" +#include "tests/scene/test_http_request.h" #include "tests/scene/test_image_texture.h" #include "tests/scene/test_image_texture_3d.h" #include "tests/scene/test_instance_placeholder.h" diff --git a/thirdparty/README.md b/thirdparty/README.md index 9a56f6baa41b..2e31c8134138 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -230,6 +230,18 @@ Files extracted from upstream source: ``` - `AUTHORS.txt` and `LICENSE.txt` +## fakeit + +- Upstream: https://github.com/eranpeer/FakeIt +- Version: 2.4.0 (cb39d8a053876f74dfeed66dd335d3041f142095, 2023) +- License: MIT + +Files extracted from upstream source: + +- `fakeit.hpp` +- `LICENSE` + + ## fonts - `DroidSans*.woff2`: diff --git a/thirdparty/fakeit/LICENSE b/thirdparty/fakeit/LICENSE new file mode 100644 index 000000000000..b8c1766d8697 --- /dev/null +++ b/thirdparty/fakeit/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Eran Pe'er + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/thirdparty/fakeit/fakeit.hpp b/thirdparty/fakeit/fakeit.hpp new file mode 100644 index 000000000000..fe29528d905c --- /dev/null +++ b/thirdparty/fakeit/fakeit.hpp @@ -0,0 +1,10075 @@ +#pragma once +/* + * FakeIt - A Simplified C++ Mocking Framework + * Copyright (c) Eran Pe'er 2013 + * Generated: 2023-04-17 21:28:50.758101 + * Distributed under the MIT License. Please refer to the LICENSE file at: + * https://github.com/eranpeer/FakeIt + */ + +#ifndef fakeit_h__ +#define fakeit_h__ + + + +#include +#include +#include +#include +#include +#if defined (__GNUG__) || _MSC_VER >= 1900 +# define FAKEIT_THROWS noexcept(false) +# define FAKEIT_NO_THROWS noexcept(true) +#elif defined (_MSC_VER) +# define FAKEIT_THROWS throw(...) +# define FAKEIT_NO_THROWS +#endif + +#ifdef _MSVC_LANG +# define FAKEIT_CPLUSPLUS _MSVC_LANG +#else +# define FAKEIT_CPLUSPLUS __cplusplus +#endif + +#ifdef __GNUG__ +# define FAKEIT_DISARM_UBSAN __attribute__((no_sanitize("undefined"))) +#else +# define FAKEIT_DISARM_UBSAN +#endif +#include +#include +#include +#include +#include +#include +#include + + +namespace fakeit { + + template + using fk_void_t = void; + + template struct bool_pack; + + template + using all_true = std::is_same, bool_pack>; + + template + struct naked_type { + typedef typename std::remove_cv::type>::type type; + }; + + template< class T > struct tuple_arg { typedef T type; }; + template< class T > struct tuple_arg < T& > { typedef T& type; }; + template< class T > struct tuple_arg < T&& > { typedef T&& type; }; + + + + + template + using ArgumentsTuple = std::tuple < arglist... > ; + + template< class T > struct test_arg { typedef T& type; }; + template< class T > struct test_arg< T& > { typedef T& type; }; + template< class T > struct test_arg< T&& > { typedef T& type; }; + + template< class T > struct production_arg { typedef T& type; }; + template< class T > struct production_arg< T& > { typedef T& type; }; + template< class T > struct production_arg< T&& > { typedef T&& type; }; + + template + class is_ostreamable { + struct no {}; +#if defined(_MSC_VER) && _MSC_VER < 1900 + template + static decltype(operator<<(std::declval(), std::declval())) test(std::ostream &s, const Type1 &t); +#else + template + static auto test(std::ostream &s, const Type1 &t) -> decltype(s << t); +#endif + static no test(...); + public: + is_ostreamable() {}; + + static const bool value = + std::is_arithmetic::value || + std::is_pointer::value || + std::is_same())), std::ostream &>::value; + }; + + + template <> + class is_ostreamable { + public: + static const bool value = true; + }; + + template + class is_ostreamable& (*)(std::basic_ios&)> { + public: + static const bool value = true; + }; + + template + class is_ostreamable& (*)(std::basic_ostream&)> { + public: + static const bool value = true; + }; + + template + struct VTableMethodType { +#if defined (__GNUG__) + typedef R(*type)(void *, arglist...); +#elif defined (_MSC_VER) + typedef R(__thiscall *type)(void *, arglist...); +#endif + }; + + templateclass test, typename T> + struct smart_test : test {}; + + templateclass test, typename T, typename A> + struct smart_test > : smart_test < test, T> {}; + + template + using smart_is_copy_constructible = smart_test < std::is_copy_constructible, T >; +} +#include +#include +#include +#include +#include +#include + +namespace fakeit { + + struct FakeitContext; + + template + struct MockObject { + virtual ~MockObject() FAKEIT_THROWS { }; + + virtual C &get() = 0; + + virtual FakeitContext &getFakeIt() = 0; + }; + + struct MethodInfo { + + static unsigned int nextMethodOrdinal() { + static std::atomic_uint ordinal{0}; + return ++ordinal; + } + + MethodInfo(unsigned int anId, std::string aName) : + _id(anId), _name(aName) { } + + unsigned int id() const { + return _id; + } + + std::string name() const { + return _name; + } + + void setName(const std::string &value) { + _name = value; + } + + private: + unsigned int _id; + std::string _name; + }; + + struct UnknownMethod { + + static MethodInfo &instance() { + static MethodInfo instance(MethodInfo::nextMethodOrdinal(), "unknown"); + return instance; + } + + }; + +} +namespace fakeit { + class Destructible { + public: + virtual ~Destructible() {} + }; +} + +namespace fakeit { + + struct Invocation : Destructible { + + static unsigned int nextInvocationOrdinal() { + static std::atomic_uint invocationOrdinal{0}; + return ++invocationOrdinal; + } + + struct Matcher { + + virtual ~Matcher() FAKEIT_THROWS { + } + + virtual bool matches(Invocation &invocation) = 0; + + virtual std::string format() const = 0; + }; + + Invocation(unsigned int ordinal, MethodInfo &method) : + _ordinal(ordinal), _method(method), _isVerified(false) { + } + + virtual ~Invocation() override = default; + + unsigned int getOrdinal() const { + return _ordinal; + } + + MethodInfo &getMethod() const { + return _method; + } + + void markAsVerified() { + _isVerified = true; + } + + bool isVerified() const { + return _isVerified; + } + + virtual std::string format() const = 0; + + private: + const unsigned int _ordinal; + MethodInfo &_method; + bool _isVerified; + }; + +} +#include +#include +#include +#include +#include + +namespace fakeit { + + template + struct Formatter; + + template <> + struct Formatter + { + static std::string format(bool const &val) + { + return val ? "true" : "false"; + } + }; + + template <> + struct Formatter + { + static std::string format(char const &val) + { + std::string s; + s += "'"; + s += val; + s += "'"; + return s; + } + }; + + template <> + struct Formatter + { + static std::string format(char const* const &val) + { + std::string s; + if(val != nullptr) + { + s += '"'; + s += val; + s += '"'; + } + else + { + s = "[nullptr]"; + } + return s; + } + }; + + template <> + struct Formatter + { + static std::string format(char* const &val) + { + return Formatter::format( val ); + } + }; + + template + struct Formatter::value>::type> { + static std::string format(C const &) + { + return "?"; + } + }; + + template + struct Formatter::value>::type> { + static std::string format(C const &val) + { + std::ostringstream os; + os << val; + return os.str(); + } + }; + + + template + using TypeFormatter = Formatter::type>; +} + +namespace fakeit { + + + template + struct TuplePrinter { + static void print(std::ostream &strm, const Tuple &t) { + TuplePrinter::print(strm, t); + strm << ", " << fakeit::TypeFormatter(t))>::format(std::get(t)); + } + }; + + template + struct TuplePrinter { + static void print(std::ostream &strm, const Tuple &t) { + strm << fakeit::TypeFormatter(t))>::format(std::get<0>(t)); + } + }; + + template + struct TuplePrinter { + static void print(std::ostream &, const Tuple &) { + } + }; + + template + void print(std::ostream &strm, const std::tuple &t) { + strm << "("; + TuplePrinter::print(strm, t); + strm << ")"; + } + + template + std::ostream &operator<<(std::ostream &strm, const std::tuple &t) { + print(strm, t); + return strm; + } + +} + + +namespace fakeit { + + template + struct ActualInvocation : public Invocation { + + struct Matcher : public virtual Destructible { + virtual bool matches(ActualInvocation &actualInvocation) = 0; + + virtual std::string format() const = 0; + }; + + ActualInvocation(unsigned int ordinal, MethodInfo &method, const typename fakeit::production_arg::type... args) : + Invocation(ordinal, method), _matcher{ nullptr } + , actualArguments{ std::forward(args)... } + { + } + + ArgumentsTuple & getActualArguments() { + return actualArguments; + } + + + void setActualMatcher(Matcher *matcher) { + this->_matcher = matcher; + } + + Matcher *getActualMatcher() { + return _matcher; + } + + virtual std::string format() const override { + std::ostringstream out; + out << getMethod().name(); + print(out, actualArguments); + return out.str(); + } + + private: + + Matcher *_matcher; + ArgumentsTuple actualArguments; + }; + + template + std::ostream &operator<<(std::ostream &strm, const ActualInvocation &ai) { + strm << ai.format(); + return strm; + } + +} + + + + + +#include + +namespace fakeit { + + struct ActualInvocationsContainer { + virtual void clear() = 0; + + virtual ~ActualInvocationsContainer() FAKEIT_NO_THROWS { } + }; + + struct ActualInvocationsSource { + virtual void getActualInvocations(std::unordered_set &into) const = 0; + + virtual ~ActualInvocationsSource() FAKEIT_NO_THROWS { } + }; + + struct InvocationsSourceProxy : public ActualInvocationsSource { + + InvocationsSourceProxy(ActualInvocationsSource *inner) : + _inner(inner) { + } + + void getActualInvocations(std::unordered_set &into) const override { + _inner->getActualInvocations(into); + } + + private: + std::shared_ptr _inner; + }; + + struct UnverifiedInvocationsSource : public ActualInvocationsSource { + + UnverifiedInvocationsSource(InvocationsSourceProxy decorated) : _decorated(decorated) { + } + + void getActualInvocations(std::unordered_set &into) const override { + std::unordered_set all; + _decorated.getActualInvocations(all); + for (fakeit::Invocation *i : all) { + if (!i->isVerified()) { + into.insert(i); + } + } + } + + private: + InvocationsSourceProxy _decorated; + }; + + struct AggregateInvocationsSource : public ActualInvocationsSource { + + AggregateInvocationsSource(std::vector &sources) : _sources(sources) { + } + + void getActualInvocations(std::unordered_set &into) const override { + std::unordered_set tmp; + for (ActualInvocationsSource *source : _sources) { + source->getActualInvocations(tmp); + } + filter(tmp, into); + } + + protected: + bool shouldInclude(fakeit::Invocation *) const { + return true; + } + + private: + std::vector _sources; + + void filter(std::unordered_set &source, std::unordered_set &target) const { + for (Invocation *i:source) { + if (shouldInclude(i)) { + target.insert(i); + } + } + } + }; +} + +namespace fakeit { + + class Sequence { + private: + + protected: + + Sequence() { + } + + virtual ~Sequence() FAKEIT_THROWS { + } + + public: + + + virtual void getExpectedSequence(std::vector &into) const = 0; + + + virtual void getInvolvedMocks(std::vector &into) const = 0; + + virtual unsigned int size() const = 0; + + friend class VerifyFunctor; + }; + + class ConcatenatedSequence : public virtual Sequence { + private: + const Sequence &s1; + const Sequence &s2; + + protected: + ConcatenatedSequence(const Sequence &seq1, const Sequence &seq2) : + s1(seq1), s2(seq2) { + } + + public: + + virtual ~ConcatenatedSequence() { + } + + unsigned int size() const override { + return s1.size() + s2.size(); + } + + const Sequence &getLeft() const { + return s1; + } + + const Sequence &getRight() const { + return s2; + } + + void getExpectedSequence(std::vector &into) const override { + s1.getExpectedSequence(into); + s2.getExpectedSequence(into); + } + + virtual void getInvolvedMocks(std::vector &into) const override { + s1.getInvolvedMocks(into); + s2.getInvolvedMocks(into); + } + + friend inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2); + }; + + class RepeatedSequence : public virtual Sequence { + private: + const Sequence &_s; + const int times; + + protected: + RepeatedSequence(const Sequence &s, const int t) : + _s(s), times(t) { + } + + public: + + ~RepeatedSequence() { + } + + unsigned int size() const override { + return _s.size() * times; + } + + friend inline RepeatedSequence operator*(const Sequence &s, int times); + + friend inline RepeatedSequence operator*(int times, const Sequence &s); + + void getInvolvedMocks(std::vector &into) const override { + _s.getInvolvedMocks(into); + } + + void getExpectedSequence(std::vector &into) const override { + for (int i = 0; i < times; i++) + _s.getExpectedSequence(into); + } + + int getTimes() const { + return times; + } + + const Sequence &getSequence() const { + return _s; + } + }; + + inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2) { + return ConcatenatedSequence(s1, s2); + } + + inline RepeatedSequence operator*(const Sequence &s, int times) { + if (times <= 0) + FAIL("times"); + return RepeatedSequence(s, times); + } + + inline RepeatedSequence operator*(int times, const Sequence &s) { + if (times <= 0) + FAIL("times"); + return RepeatedSequence(s, times); + } + +} + +namespace fakeit { + + enum class VerificationType { + Exact, AtLeast, NoMoreInvocations + }; + + enum class UnexpectedType { + Unmocked, Unmatched + }; + + struct VerificationEvent { + + VerificationEvent(VerificationType aVerificationType) : + _verificationType(aVerificationType), _line(0) { + } + + virtual ~VerificationEvent() = default; + + VerificationType verificationType() const { + return _verificationType; + } + + void setFileInfo(const char * aFile, int aLine, const char * aCallingMethod) { + _file = aFile; + _callingMethod = aCallingMethod; + _line = aLine; + } + + const char * file() const { + return _file; + } + + int line() const { + return _line; + } + + const char * callingMethod() const { + return _callingMethod; + } + + private: + VerificationType _verificationType; + const char * _file; + int _line; + const char * _callingMethod; + }; + + struct NoMoreInvocationsVerificationEvent : public VerificationEvent { + + ~NoMoreInvocationsVerificationEvent() = default; + + NoMoreInvocationsVerificationEvent( + std::vector &allTheIvocations, + std::vector &anUnverifedIvocations) : + VerificationEvent(VerificationType::NoMoreInvocations), + _allIvocations(allTheIvocations), + _unverifedIvocations(anUnverifedIvocations) { + } + + const std::vector &allIvocations() const { + return _allIvocations; + } + + const std::vector &unverifedIvocations() const { + return _unverifedIvocations; + } + + private: + const std::vector _allIvocations; + const std::vector _unverifedIvocations; + }; + + struct SequenceVerificationEvent : public VerificationEvent { + + ~SequenceVerificationEvent() = default; + + SequenceVerificationEvent(VerificationType aVerificationType, + std::vector &anExpectedPattern, + std::vector &anActualSequence, + int anExpectedCount, + int anActualCount) : + VerificationEvent(aVerificationType), + _expectedPattern(anExpectedPattern), + _actualSequence(anActualSequence), + _expectedCount(anExpectedCount), + _actualCount(anActualCount) + { + } + + const std::vector &expectedPattern() const { + return _expectedPattern; + } + + const std::vector &actualSequence() const { + return _actualSequence; + } + + int expectedCount() const { + return _expectedCount; + } + + int actualCount() const { + return _actualCount; + } + + private: + const std::vector _expectedPattern; + const std::vector _actualSequence; + const int _expectedCount; + const int _actualCount; + }; + + struct UnexpectedMethodCallEvent { + UnexpectedMethodCallEvent(UnexpectedType unexpectedType, const Invocation &invocation) : + _unexpectedType(unexpectedType), _invocation(invocation) { + } + + const Invocation &getInvocation() const { + return _invocation; + } + + UnexpectedType getUnexpectedType() const { + return _unexpectedType; + } + + const UnexpectedType _unexpectedType; + const Invocation &_invocation; + }; + +} + +namespace fakeit { + + struct VerificationEventHandler { + virtual void handle(const SequenceVerificationEvent &e) = 0; + + virtual void handle(const NoMoreInvocationsVerificationEvent &e) = 0; + + virtual ~VerificationEventHandler() { } + }; + + struct EventHandler : public VerificationEventHandler { + using VerificationEventHandler::handle; + + virtual void handle(const UnexpectedMethodCallEvent &e) = 0; + }; + +} +#include +#include + +namespace fakeit { + + struct UnexpectedMethodCallEvent; + struct SequenceVerificationEvent; + struct NoMoreInvocationsVerificationEvent; + + struct EventFormatter { + + virtual std::string format(const fakeit::UnexpectedMethodCallEvent &e) = 0; + + virtual std::string format(const fakeit::SequenceVerificationEvent &e) = 0; + + virtual std::string format(const fakeit::NoMoreInvocationsVerificationEvent &e) = 0; + + virtual ~EventFormatter() { } + }; + +} +#ifdef FAKEIT_ASSERT_ON_UNEXPECTED_METHOD_INVOCATION +#include +#endif + +namespace fakeit { + + struct FakeitContext : public EventHandler, protected EventFormatter { + + virtual ~FakeitContext() = default; + + void handle(const UnexpectedMethodCallEvent &e) override { + fireEvent(e); + auto &eh = getTestingFrameworkAdapter(); + #ifdef FAKEIT_ASSERT_ON_UNEXPECTED_METHOD_INVOCATION + assert(!"Unexpected method invocation"); + #endif + eh.handle(e); + } + + void handle(const SequenceVerificationEvent &e) override { + fireEvent(e); + auto &eh = getTestingFrameworkAdapter(); + return eh.handle(e); + } + + void handle(const NoMoreInvocationsVerificationEvent &e) override { + fireEvent(e); + auto &eh = getTestingFrameworkAdapter(); + return eh.handle(e); + } + + std::string format(const UnexpectedMethodCallEvent &e) override { + auto &eventFormatter = getEventFormatter(); + return eventFormatter.format(e); + } + + std::string format(const SequenceVerificationEvent &e) override { + auto &eventFormatter = getEventFormatter(); + return eventFormatter.format(e); + } + + std::string format(const NoMoreInvocationsVerificationEvent &e) override { + auto &eventFormatter = getEventFormatter(); + return eventFormatter.format(e); + } + + void addEventHandler(EventHandler &eventListener) { + _eventListeners.push_back(&eventListener); + } + + void clearEventHandlers() { + _eventListeners.clear(); + } + + protected: + virtual EventHandler &getTestingFrameworkAdapter() = 0; + + virtual EventFormatter &getEventFormatter() = 0; + + private: + std::vector _eventListeners; + + void fireEvent(const NoMoreInvocationsVerificationEvent &evt) { + for (auto listener : _eventListeners) + listener->handle(evt); + } + + void fireEvent(const UnexpectedMethodCallEvent &evt) { + for (auto listener : _eventListeners) + listener->handle(evt); + } + + void fireEvent(const SequenceVerificationEvent &evt) { + for (auto listener : _eventListeners) + listener->handle(evt); + } + + }; + +} +#include +#include + +namespace fakeit { + + struct DefaultEventFormatter : public EventFormatter { + + virtual std::string format(const UnexpectedMethodCallEvent &e) override { + std::ostringstream out; + out << "Unexpected method invocation: "; + out << e.getInvocation().format() << std::endl; + if (UnexpectedType::Unmatched == e.getUnexpectedType()) { + out << " Could not find any recorded behavior to support this method call."; + } else { + out << " An unmocked method was invoked. All used virtual methods must be stubbed!"; + } + return out.str(); + } + + + virtual std::string format(const SequenceVerificationEvent &e) override { + std::ostringstream out; + out << "Verification error" << std::endl; + + out << "Expected pattern: "; + const std::vector expectedPattern = e.expectedPattern(); + out << formatExpectedPattern(expectedPattern) << std::endl; + + out << "Expected matches: "; + formatExpectedCount(out, e.verificationType(), e.expectedCount()); + out << std::endl; + + out << "Actual matches : " << e.actualCount() << std::endl; + + auto actualSequence = e.actualSequence(); + out << "Actual sequence : total of " << actualSequence.size() << " actual invocations"; + if (actualSequence.size() == 0) { + out << "."; + } else { + out << ":" << std::endl; + } + formatInvocationList(out, actualSequence); + + return out.str(); + } + + virtual std::string format(const NoMoreInvocationsVerificationEvent &e) override { + std::ostringstream out; + out << "Verification error" << std::endl; + out << "Expected no more invocations!! but the following unverified invocations were found:" << std::endl; + formatInvocationList(out, e.unverifedIvocations()); + return out.str(); + } + + static std::string formatExpectedPattern(const std::vector &expectedPattern) { + std::string expectedPatternStr; + for (unsigned int i = 0; i < expectedPattern.size(); i++) { + Sequence *s = expectedPattern[i]; + expectedPatternStr += formatSequence(*s); + if (i < expectedPattern.size() - 1) + expectedPatternStr += " ... "; + } + return expectedPatternStr; + } + + private: + + static std::string formatSequence(const Sequence &val) { + const ConcatenatedSequence *cs = dynamic_cast(&val); + if (cs) { + return format(*cs); + } + const RepeatedSequence *rs = dynamic_cast(&val); + if (rs) { + return format(*rs); + } + + + std::vector vec; + val.getExpectedSequence(vec); + return vec[0]->format(); + } + + static void formatExpectedCount(std::ostream &out, fakeit::VerificationType verificationType, + int expectedCount) { + if (verificationType == fakeit::VerificationType::Exact) + out << "exactly "; + + if (verificationType == fakeit::VerificationType::AtLeast) + out << "at least "; + + out << expectedCount; + } + + static void formatInvocationList(std::ostream &out, const std::vector &actualSequence) { + size_t max_size = actualSequence.size(); + if (max_size > 50) + max_size = 50; + + for (unsigned int i = 0; i < max_size; i++) { + out << " "; + auto invocation = actualSequence[i]; + out << invocation->format(); + if (i < max_size - 1) + out << std::endl; + } + + if (actualSequence.size() > max_size) + out << std::endl << " ..."; + } + + static std::string format(const ConcatenatedSequence &val) { + std::ostringstream out; + out << formatSequence(val.getLeft()) << " + " << formatSequence(val.getRight()); + return out.str(); + } + + static std::string format(const RepeatedSequence &val) { + std::ostringstream out; + const ConcatenatedSequence *cs = dynamic_cast(&val.getSequence()); + const RepeatedSequence *rs = dynamic_cast(&val.getSequence()); + if (rs || cs) + out << '('; + out << formatSequence(val.getSequence()); + if (rs || cs) + out << ')'; + + out << " * " << val.getTimes(); + return out.str(); + } + }; +} +#include + + + +namespace fakeit { +#if FAKEIT_CPLUSPLUS >= 201703L || defined(__cpp_lib_uncaught_exceptions) + inline bool UncaughtException () { + return std::uncaught_exceptions() >= 1; + } +#else + inline bool UncaughtException () { + return std::uncaught_exception(); + } +#endif + + struct FakeitException { + std::exception err; + + virtual ~FakeitException() = default; + + virtual std::string what() const = 0; + + friend std::ostream &operator<<(std::ostream &os, const FakeitException &val) { + os << val.what(); + return os; + } + }; + +/* clang-format off */ + struct UnexpectedMethodCallException : public FakeitException { + + UnexpectedMethodCallException(std::string format) : + _format(format) { + } + + virtual std::string what() const override { + return _format; + } + + private: + std::string _format; + }; +/* clang-format on */ +} + +namespace fakeit { + + struct DefaultEventLogger : public fakeit::EventHandler { + + DefaultEventLogger(EventFormatter &formatter) : _formatter(formatter), _out(std::cout) { } + + virtual void handle(const UnexpectedMethodCallEvent &e) override { + _out << _formatter.format(e) << std::endl; + } + + virtual void handle(const SequenceVerificationEvent &e) override { + _out << _formatter.format(e) << std::endl; + } + + virtual void handle(const NoMoreInvocationsVerificationEvent &e) override { + _out << _formatter.format(e) << std::endl; + } + + private: + EventFormatter &_formatter; + std::ostream &_out; + }; + +} + +namespace fakeit { + + class AbstractFakeit : public FakeitContext { + public: + virtual ~AbstractFakeit() = default; + + protected: + + virtual fakeit::EventHandler &accessTestingFrameworkAdapter() = 0; + + virtual EventFormatter &accessEventFormatter() = 0; + }; + + class DefaultFakeit : public AbstractFakeit { + DefaultEventFormatter _formatter; + fakeit::EventFormatter *_customFormatter; + fakeit::EventHandler *_testingFrameworkAdapter; + + public: + + DefaultFakeit() : _formatter(), + _customFormatter(nullptr), + _testingFrameworkAdapter(nullptr) { + } + + virtual ~DefaultFakeit() = default; + + void setCustomEventFormatter(fakeit::EventFormatter &customEventFormatter) { + _customFormatter = &customEventFormatter; + } + + void resetCustomEventFormatter() { + _customFormatter = nullptr; + } + + void setTestingFrameworkAdapter(fakeit::EventHandler &testingFrameforkAdapter) { + _testingFrameworkAdapter = &testingFrameforkAdapter; + } + + void resetTestingFrameworkAdapter() { + _testingFrameworkAdapter = nullptr; + } + + protected: + + fakeit::EventHandler &getTestingFrameworkAdapter() override { + if (_testingFrameworkAdapter) + return *_testingFrameworkAdapter; + return accessTestingFrameworkAdapter(); + } + + EventFormatter &getEventFormatter() override { + if (_customFormatter) + return *_customFormatter; + return accessEventFormatter(); + } + + EventFormatter &accessEventFormatter() override { + return _formatter; + } + + }; +} +#include +#include +#include + +namespace fakeit { + + template + static std::string to_string(const T &n) { + std::ostringstream stm; + stm << n; + return stm.str(); + } + +} +#include "thirdparty/doctest/doctest.h" + +namespace fakeit +{ + class DoctestAdapter : public EventHandler + { + EventFormatter &_formatter; + + public: + virtual ~DoctestAdapter() = default; + + DoctestAdapter(EventFormatter &formatter) + : _formatter(formatter) {} + + void fail(const char* fileName, + int lineNumber, + std::string fomattedMessage, + bool fatalFailure) + { + if (fatalFailure) + { + DOCTEST_ADD_FAIL_AT(fileName, lineNumber, fomattedMessage); + } + else + { + DOCTEST_ADD_FAIL_CHECK_AT(fileName, lineNumber, fomattedMessage); + } + } + + void handle(const UnexpectedMethodCallEvent &evt) override + { + fail("Unknown file", 0, _formatter.format(evt), true); + } + + void handle(const SequenceVerificationEvent &evt) override + { + fail(evt.file(), evt.line(), _formatter.format(evt), false); + } + + void handle(const NoMoreInvocationsVerificationEvent &evt) override + { + fail(evt.file(), evt.line(), _formatter.format(evt), false); + } + }; + + class DoctestFakeit : public DefaultFakeit + { + public: + virtual ~DoctestFakeit() = default; + + DoctestFakeit() : _doctestAdapter(*this) {} + + static DoctestFakeit &getInstance() + { + static DoctestFakeit instance; + return instance; + } + + protected: + fakeit::EventHandler &accessTestingFrameworkAdapter() override + { + return _doctestAdapter; + } + + private: + DoctestAdapter _doctestAdapter; + }; +} + +static fakeit::DefaultFakeit& Fakeit = fakeit::DoctestFakeit::getInstance(); + + +#include +#include + +#include +#undef max +#include +#include +#include +#include +#include +#include + +#include +#include +namespace fakeit { + + struct VirtualOffsetSelector { + + unsigned int offset; + + virtual unsigned int offset0(int) { + return offset = 0; + } + + virtual unsigned int offset1(int) { + return offset = 1; + } + + virtual unsigned int offset2(int) { + return offset = 2; + } + + virtual unsigned int offset3(int) { + return offset = 3; + } + + virtual unsigned int offset4(int) { + return offset = 4; + } + + virtual unsigned int offset5(int) { + return offset = 5; + } + + virtual unsigned int offset6(int) { + return offset = 6; + } + + virtual unsigned int offset7(int) { + return offset = 7; + } + + virtual unsigned int offset8(int) { + return offset = 8; + } + + virtual unsigned int offset9(int) { + return offset = 9; + } + + virtual unsigned int offset10(int) { + return offset = 10; + } + + virtual unsigned int offset11(int) { + return offset = 11; + } + + virtual unsigned int offset12(int) { + return offset = 12; + } + + virtual unsigned int offset13(int) { + return offset = 13; + } + + virtual unsigned int offset14(int) { + return offset = 14; + } + + virtual unsigned int offset15(int) { + return offset = 15; + } + + virtual unsigned int offset16(int) { + return offset = 16; + } + + virtual unsigned int offset17(int) { + return offset = 17; + } + + virtual unsigned int offset18(int) { + return offset = 18; + } + + virtual unsigned int offset19(int) { + return offset = 19; + } + + virtual unsigned int offset20(int) { + return offset = 20; + } + + virtual unsigned int offset21(int) { + return offset = 21; + } + + virtual unsigned int offset22(int) { + return offset = 22; + } + + virtual unsigned int offset23(int) { + return offset = 23; + } + + virtual unsigned int offset24(int) { + return offset = 24; + } + + virtual unsigned int offset25(int) { + return offset = 25; + } + + virtual unsigned int offset26(int) { + return offset = 26; + } + + virtual unsigned int offset27(int) { + return offset = 27; + } + + virtual unsigned int offset28(int) { + return offset = 28; + } + + virtual unsigned int offset29(int) { + return offset = 29; + } + + virtual unsigned int offset30(int) { + return offset = 30; + } + + virtual unsigned int offset31(int) { + return offset = 31; + } + + virtual unsigned int offset32(int) { + return offset = 32; + } + + virtual unsigned int offset33(int) { + return offset = 33; + } + + virtual unsigned int offset34(int) { + return offset = 34; + } + + virtual unsigned int offset35(int) { + return offset = 35; + } + + virtual unsigned int offset36(int) { + return offset = 36; + } + + virtual unsigned int offset37(int) { + return offset = 37; + } + + virtual unsigned int offset38(int) { + return offset = 38; + } + + virtual unsigned int offset39(int) { + return offset = 39; + } + + virtual unsigned int offset40(int) { + return offset = 40; + } + + virtual unsigned int offset41(int) { + return offset = 41; + } + + virtual unsigned int offset42(int) { + return offset = 42; + } + + virtual unsigned int offset43(int) { + return offset = 43; + } + + virtual unsigned int offset44(int) { + return offset = 44; + } + + virtual unsigned int offset45(int) { + return offset = 45; + } + + virtual unsigned int offset46(int) { + return offset = 46; + } + + virtual unsigned int offset47(int) { + return offset = 47; + } + + virtual unsigned int offset48(int) { + return offset = 48; + } + + virtual unsigned int offset49(int) { + return offset = 49; + } + + virtual unsigned int offset50(int) { + return offset = 50; + } + + virtual unsigned int offset51(int) { + return offset = 51; + } + + virtual unsigned int offset52(int) { + return offset = 52; + } + + virtual unsigned int offset53(int) { + return offset = 53; + } + + virtual unsigned int offset54(int) { + return offset = 54; + } + + virtual unsigned int offset55(int) { + return offset = 55; + } + + virtual unsigned int offset56(int) { + return offset = 56; + } + + virtual unsigned int offset57(int) { + return offset = 57; + } + + virtual unsigned int offset58(int) { + return offset = 58; + } + + virtual unsigned int offset59(int) { + return offset = 59; + } + + virtual unsigned int offset60(int) { + return offset = 60; + } + + virtual unsigned int offset61(int) { + return offset = 61; + } + + virtual unsigned int offset62(int) { + return offset = 62; + } + + virtual unsigned int offset63(int) { + return offset = 63; + } + + virtual unsigned int offset64(int) { + return offset = 64; + } + + virtual unsigned int offset65(int) { + return offset = 65; + } + + virtual unsigned int offset66(int) { + return offset = 66; + } + + virtual unsigned int offset67(int) { + return offset = 67; + } + + virtual unsigned int offset68(int) { + return offset = 68; + } + + virtual unsigned int offset69(int) { + return offset = 69; + } + + virtual unsigned int offset70(int) { + return offset = 70; + } + + virtual unsigned int offset71(int) { + return offset = 71; + } + + virtual unsigned int offset72(int) { + return offset = 72; + } + + virtual unsigned int offset73(int) { + return offset = 73; + } + + virtual unsigned int offset74(int) { + return offset = 74; + } + + virtual unsigned int offset75(int) { + return offset = 75; + } + + virtual unsigned int offset76(int) { + return offset = 76; + } + + virtual unsigned int offset77(int) { + return offset = 77; + } + + virtual unsigned int offset78(int) { + return offset = 78; + } + + virtual unsigned int offset79(int) { + return offset = 79; + } + + virtual unsigned int offset80(int) { + return offset = 80; + } + + virtual unsigned int offset81(int) { + return offset = 81; + } + + virtual unsigned int offset82(int) { + return offset = 82; + } + + virtual unsigned int offset83(int) { + return offset = 83; + } + + virtual unsigned int offset84(int) { + return offset = 84; + } + + virtual unsigned int offset85(int) { + return offset = 85; + } + + virtual unsigned int offset86(int) { + return offset = 86; + } + + virtual unsigned int offset87(int) { + return offset = 87; + } + + virtual unsigned int offset88(int) { + return offset = 88; + } + + virtual unsigned int offset89(int) { + return offset = 89; + } + + virtual unsigned int offset90(int) { + return offset = 90; + } + + virtual unsigned int offset91(int) { + return offset = 91; + } + + virtual unsigned int offset92(int) { + return offset = 92; + } + + virtual unsigned int offset93(int) { + return offset = 93; + } + + virtual unsigned int offset94(int) { + return offset = 94; + } + + virtual unsigned int offset95(int) { + return offset = 95; + } + + virtual unsigned int offset96(int) { + return offset = 96; + } + + virtual unsigned int offset97(int) { + return offset = 97; + } + + virtual unsigned int offset98(int) { + return offset = 98; + } + + virtual unsigned int offset99(int) { + return offset = 99; + } + + virtual unsigned int offset100(int) { + return offset = 100; + } + + virtual unsigned int offset101(int) { + return offset = 101; + } + + virtual unsigned int offset102(int) { + return offset = 102; + } + + virtual unsigned int offset103(int) { + return offset = 103; + } + + virtual unsigned int offset104(int) { + return offset = 104; + } + + virtual unsigned int offset105(int) { + return offset = 105; + } + + virtual unsigned int offset106(int) { + return offset = 106; + } + + virtual unsigned int offset107(int) { + return offset = 107; + } + + virtual unsigned int offset108(int) { + return offset = 108; + } + + virtual unsigned int offset109(int) { + return offset = 109; + } + + virtual unsigned int offset110(int) { + return offset = 110; + } + + virtual unsigned int offset111(int) { + return offset = 111; + } + + virtual unsigned int offset112(int) { + return offset = 112; + } + + virtual unsigned int offset113(int) { + return offset = 113; + } + + virtual unsigned int offset114(int) { + return offset = 114; + } + + virtual unsigned int offset115(int) { + return offset = 115; + } + + virtual unsigned int offset116(int) { + return offset = 116; + } + + virtual unsigned int offset117(int) { + return offset = 117; + } + + virtual unsigned int offset118(int) { + return offset = 118; + } + + virtual unsigned int offset119(int) { + return offset = 119; + } + + virtual unsigned int offset120(int) { + return offset = 120; + } + + virtual unsigned int offset121(int) { + return offset = 121; + } + + virtual unsigned int offset122(int) { + return offset = 122; + } + + virtual unsigned int offset123(int) { + return offset = 123; + } + + virtual unsigned int offset124(int) { + return offset = 124; + } + + virtual unsigned int offset125(int) { + return offset = 125; + } + + virtual unsigned int offset126(int) { + return offset = 126; + } + + virtual unsigned int offset127(int) { + return offset = 127; + } + + virtual unsigned int offset128(int) { + return offset = 128; + } + + virtual unsigned int offset129(int) { + return offset = 129; + } + + virtual unsigned int offset130(int) { + return offset = 130; + } + + virtual unsigned int offset131(int) { + return offset = 131; + } + + virtual unsigned int offset132(int) { + return offset = 132; + } + + virtual unsigned int offset133(int) { + return offset = 133; + } + + virtual unsigned int offset134(int) { + return offset = 134; + } + + virtual unsigned int offset135(int) { + return offset = 135; + } + + virtual unsigned int offset136(int) { + return offset = 136; + } + + virtual unsigned int offset137(int) { + return offset = 137; + } + + virtual unsigned int offset138(int) { + return offset = 138; + } + + virtual unsigned int offset139(int) { + return offset = 139; + } + + virtual unsigned int offset140(int) { + return offset = 140; + } + + virtual unsigned int offset141(int) { + return offset = 141; + } + + virtual unsigned int offset142(int) { + return offset = 142; + } + + virtual unsigned int offset143(int) { + return offset = 143; + } + + virtual unsigned int offset144(int) { + return offset = 144; + } + + virtual unsigned int offset145(int) { + return offset = 145; + } + + virtual unsigned int offset146(int) { + return offset = 146; + } + + virtual unsigned int offset147(int) { + return offset = 147; + } + + virtual unsigned int offset148(int) { + return offset = 148; + } + + virtual unsigned int offset149(int) { + return offset = 149; + } + + virtual unsigned int offset150(int) { + return offset = 150; + } + + virtual unsigned int offset151(int) { + return offset = 151; + } + + virtual unsigned int offset152(int) { + return offset = 152; + } + + virtual unsigned int offset153(int) { + return offset = 153; + } + + virtual unsigned int offset154(int) { + return offset = 154; + } + + virtual unsigned int offset155(int) { + return offset = 155; + } + + virtual unsigned int offset156(int) { + return offset = 156; + } + + virtual unsigned int offset157(int) { + return offset = 157; + } + + virtual unsigned int offset158(int) { + return offset = 158; + } + + virtual unsigned int offset159(int) { + return offset = 159; + } + + virtual unsigned int offset160(int) { + return offset = 160; + } + + virtual unsigned int offset161(int) { + return offset = 161; + } + + virtual unsigned int offset162(int) { + return offset = 162; + } + + virtual unsigned int offset163(int) { + return offset = 163; + } + + virtual unsigned int offset164(int) { + return offset = 164; + } + + virtual unsigned int offset165(int) { + return offset = 165; + } + + virtual unsigned int offset166(int) { + return offset = 166; + } + + virtual unsigned int offset167(int) { + return offset = 167; + } + + virtual unsigned int offset168(int) { + return offset = 168; + } + + virtual unsigned int offset169(int) { + return offset = 169; + } + + virtual unsigned int offset170(int) { + return offset = 170; + } + + virtual unsigned int offset171(int) { + return offset = 171; + } + + virtual unsigned int offset172(int) { + return offset = 172; + } + + virtual unsigned int offset173(int) { + return offset = 173; + } + + virtual unsigned int offset174(int) { + return offset = 174; + } + + virtual unsigned int offset175(int) { + return offset = 175; + } + + virtual unsigned int offset176(int) { + return offset = 176; + } + + virtual unsigned int offset177(int) { + return offset = 177; + } + + virtual unsigned int offset178(int) { + return offset = 178; + } + + virtual unsigned int offset179(int) { + return offset = 179; + } + + virtual unsigned int offset180(int) { + return offset = 180; + } + + virtual unsigned int offset181(int) { + return offset = 181; + } + + virtual unsigned int offset182(int) { + return offset = 182; + } + + virtual unsigned int offset183(int) { + return offset = 183; + } + + virtual unsigned int offset184(int) { + return offset = 184; + } + + virtual unsigned int offset185(int) { + return offset = 185; + } + + virtual unsigned int offset186(int) { + return offset = 186; + } + + virtual unsigned int offset187(int) { + return offset = 187; + } + + virtual unsigned int offset188(int) { + return offset = 188; + } + + virtual unsigned int offset189(int) { + return offset = 189; + } + + virtual unsigned int offset190(int) { + return offset = 190; + } + + virtual unsigned int offset191(int) { + return offset = 191; + } + + virtual unsigned int offset192(int) { + return offset = 192; + } + + virtual unsigned int offset193(int) { + return offset = 193; + } + + virtual unsigned int offset194(int) { + return offset = 194; + } + + virtual unsigned int offset195(int) { + return offset = 195; + } + + virtual unsigned int offset196(int) { + return offset = 196; + } + + virtual unsigned int offset197(int) { + return offset = 197; + } + + virtual unsigned int offset198(int) { + return offset = 198; + } + + virtual unsigned int offset199(int) { + return offset = 199; + } + + + virtual unsigned int offset200(int) { + return offset = 200; + } + + virtual unsigned int offset201(int) { + return offset = 201; + } + + virtual unsigned int offset202(int) { + return offset = 202; + } + + virtual unsigned int offset203(int) { + return offset = 203; + } + + virtual unsigned int offset204(int) { + return offset = 204; + } + + virtual unsigned int offset205(int) { + return offset = 205; + } + + virtual unsigned int offset206(int) { + return offset = 206; + } + + virtual unsigned int offset207(int) { + return offset = 207; + } + + virtual unsigned int offset208(int) { + return offset = 208; + } + + virtual unsigned int offset209(int) { + return offset = 209; + } + + virtual unsigned int offset210(int) { + return offset = 210; + } + + virtual unsigned int offset211(int) { + return offset = 211; + } + + virtual unsigned int offset212(int) { + return offset = 212; + } + + virtual unsigned int offset213(int) { + return offset = 213; + } + + virtual unsigned int offset214(int) { + return offset = 214; + } + + virtual unsigned int offset215(int) { + return offset = 215; + } + + virtual unsigned int offset216(int) { + return offset = 216; + } + + virtual unsigned int offset217(int) { + return offset = 217; + } + + virtual unsigned int offset218(int) { + return offset = 218; + } + + virtual unsigned int offset219(int) { + return offset = 219; + } + + virtual unsigned int offset220(int) { + return offset = 220; + } + + virtual unsigned int offset221(int) { + return offset = 221; + } + + virtual unsigned int offset222(int) { + return offset = 222; + } + + virtual unsigned int offset223(int) { + return offset = 223; + } + + virtual unsigned int offset224(int) { + return offset = 224; + } + + virtual unsigned int offset225(int) { + return offset = 225; + } + + virtual unsigned int offset226(int) { + return offset = 226; + } + + virtual unsigned int offset227(int) { + return offset = 227; + } + + virtual unsigned int offset228(int) { + return offset = 228; + } + + virtual unsigned int offset229(int) { + return offset = 229; + } + + virtual unsigned int offset230(int) { + return offset = 230; + } + + virtual unsigned int offset231(int) { + return offset = 231; + } + + virtual unsigned int offset232(int) { + return offset = 232; + } + + virtual unsigned int offset233(int) { + return offset = 233; + } + + virtual unsigned int offset234(int) { + return offset = 234; + } + + virtual unsigned int offset235(int) { + return offset = 235; + } + + virtual unsigned int offset236(int) { + return offset = 236; + } + + virtual unsigned int offset237(int) { + return offset = 237; + } + + virtual unsigned int offset238(int) { + return offset = 238; + } + + virtual unsigned int offset239(int) { + return offset = 239; + } + + virtual unsigned int offset240(int) { + return offset = 240; + } + + virtual unsigned int offset241(int) { + return offset = 241; + } + + virtual unsigned int offset242(int) { + return offset = 242; + } + + virtual unsigned int offset243(int) { + return offset = 243; + } + + virtual unsigned int offset244(int) { + return offset = 244; + } + + virtual unsigned int offset245(int) { + return offset = 245; + } + + virtual unsigned int offset246(int) { + return offset = 246; + } + + virtual unsigned int offset247(int) { + return offset = 247; + } + + virtual unsigned int offset248(int) { + return offset = 248; + } + + virtual unsigned int offset249(int) { + return offset = 249; + } + + virtual unsigned int offset250(int) { + return offset = 250; + } + + virtual unsigned int offset251(int) { + return offset = 251; + } + + virtual unsigned int offset252(int) { + return offset = 252; + } + + virtual unsigned int offset253(int) { + return offset = 253; + } + + virtual unsigned int offset254(int) { + return offset = 254; + } + + virtual unsigned int offset255(int) { + return offset = 255; + } + + virtual unsigned int offset256(int) { + return offset = 256; + } + + virtual unsigned int offset257(int) { + return offset = 257; + } + + virtual unsigned int offset258(int) { + return offset = 258; + } + + virtual unsigned int offset259(int) { + return offset = 259; + } + + virtual unsigned int offset260(int) { + return offset = 260; + } + + virtual unsigned int offset261(int) { + return offset = 261; + } + + virtual unsigned int offset262(int) { + return offset = 262; + } + + virtual unsigned int offset263(int) { + return offset = 263; + } + + virtual unsigned int offset264(int) { + return offset = 264; + } + + virtual unsigned int offset265(int) { + return offset = 265; + } + + virtual unsigned int offset266(int) { + return offset = 266; + } + + virtual unsigned int offset267(int) { + return offset = 267; + } + + virtual unsigned int offset268(int) { + return offset = 268; + } + + virtual unsigned int offset269(int) { + return offset = 269; + } + + virtual unsigned int offset270(int) { + return offset = 270; + } + + virtual unsigned int offset271(int) { + return offset = 271; + } + + virtual unsigned int offset272(int) { + return offset = 272; + } + + virtual unsigned int offset273(int) { + return offset = 273; + } + + virtual unsigned int offset274(int) { + return offset = 274; + } + + virtual unsigned int offset275(int) { + return offset = 275; + } + + virtual unsigned int offset276(int) { + return offset = 276; + } + + virtual unsigned int offset277(int) { + return offset = 277; + } + + virtual unsigned int offset278(int) { + return offset = 278; + } + + virtual unsigned int offset279(int) { + return offset = 279; + } + + virtual unsigned int offset280(int) { + return offset = 280; + } + + virtual unsigned int offset281(int) { + return offset = 281; + } + + virtual unsigned int offset282(int) { + return offset = 282; + } + + virtual unsigned int offset283(int) { + return offset = 283; + } + + virtual unsigned int offset284(int) { + return offset = 284; + } + + virtual unsigned int offset285(int) { + return offset = 285; + } + + virtual unsigned int offset286(int) { + return offset = 286; + } + + virtual unsigned int offset287(int) { + return offset = 287; + } + + virtual unsigned int offset288(int) { + return offset = 288; + } + + virtual unsigned int offset289(int) { + return offset = 289; + } + + virtual unsigned int offset290(int) { + return offset = 290; + } + + virtual unsigned int offset291(int) { + return offset = 291; + } + + virtual unsigned int offset292(int) { + return offset = 292; + } + + virtual unsigned int offset293(int) { + return offset = 293; + } + + virtual unsigned int offset294(int) { + return offset = 294; + } + + virtual unsigned int offset295(int) { + return offset = 295; + } + + virtual unsigned int offset296(int) { + return offset = 296; + } + + virtual unsigned int offset297(int) { + return offset = 297; + } + + virtual unsigned int offset298(int) { + return offset = 298; + } + + virtual unsigned int offset299(int) { + return offset = 299; + } + + + virtual unsigned int offset300(int) { + return offset = 300; + } + + virtual unsigned int offset301(int) { + return offset = 301; + } + + virtual unsigned int offset302(int) { + return offset = 302; + } + + virtual unsigned int offset303(int) { + return offset = 303; + } + + virtual unsigned int offset304(int) { + return offset = 304; + } + + virtual unsigned int offset305(int) { + return offset = 305; + } + + virtual unsigned int offset306(int) { + return offset = 306; + } + + virtual unsigned int offset307(int) { + return offset = 307; + } + + virtual unsigned int offset308(int) { + return offset = 308; + } + + virtual unsigned int offset309(int) { + return offset = 309; + } + + virtual unsigned int offset310(int) { + return offset = 310; + } + + virtual unsigned int offset311(int) { + return offset = 311; + } + + virtual unsigned int offset312(int) { + return offset = 312; + } + + virtual unsigned int offset313(int) { + return offset = 313; + } + + virtual unsigned int offset314(int) { + return offset = 314; + } + + virtual unsigned int offset315(int) { + return offset = 315; + } + + virtual unsigned int offset316(int) { + return offset = 316; + } + + virtual unsigned int offset317(int) { + return offset = 317; + } + + virtual unsigned int offset318(int) { + return offset = 318; + } + + virtual unsigned int offset319(int) { + return offset = 319; + } + + virtual unsigned int offset320(int) { + return offset = 320; + } + + virtual unsigned int offset321(int) { + return offset = 321; + } + + virtual unsigned int offset322(int) { + return offset = 322; + } + + virtual unsigned int offset323(int) { + return offset = 323; + } + + virtual unsigned int offset324(int) { + return offset = 324; + } + + virtual unsigned int offset325(int) { + return offset = 325; + } + + virtual unsigned int offset326(int) { + return offset = 326; + } + + virtual unsigned int offset327(int) { + return offset = 327; + } + + virtual unsigned int offset328(int) { + return offset = 328; + } + + virtual unsigned int offset329(int) { + return offset = 329; + } + + virtual unsigned int offset330(int) { + return offset = 330; + } + + virtual unsigned int offset331(int) { + return offset = 331; + } + + virtual unsigned int offset332(int) { + return offset = 332; + } + + virtual unsigned int offset333(int) { + return offset = 333; + } + + virtual unsigned int offset334(int) { + return offset = 334; + } + + virtual unsigned int offset335(int) { + return offset = 335; + } + + virtual unsigned int offset336(int) { + return offset = 336; + } + + virtual unsigned int offset337(int) { + return offset = 337; + } + + virtual unsigned int offset338(int) { + return offset = 338; + } + + virtual unsigned int offset339(int) { + return offset = 339; + } + + virtual unsigned int offset340(int) { + return offset = 340; + } + + virtual unsigned int offset341(int) { + return offset = 341; + } + + virtual unsigned int offset342(int) { + return offset = 342; + } + + virtual unsigned int offset343(int) { + return offset = 343; + } + + virtual unsigned int offset344(int) { + return offset = 344; + } + + virtual unsigned int offset345(int) { + return offset = 345; + } + + virtual unsigned int offset346(int) { + return offset = 346; + } + + virtual unsigned int offset347(int) { + return offset = 347; + } + + virtual unsigned int offset348(int) { + return offset = 348; + } + + virtual unsigned int offset349(int) { + return offset = 349; + } + + virtual unsigned int offset350(int) { + return offset = 350; + } + + virtual unsigned int offset351(int) { + return offset = 351; + } + + virtual unsigned int offset352(int) { + return offset = 352; + } + + virtual unsigned int offset353(int) { + return offset = 353; + } + + virtual unsigned int offset354(int) { + return offset = 354; + } + + virtual unsigned int offset355(int) { + return offset = 355; + } + + virtual unsigned int offset356(int) { + return offset = 356; + } + + virtual unsigned int offset357(int) { + return offset = 357; + } + + virtual unsigned int offset358(int) { + return offset = 358; + } + + virtual unsigned int offset359(int) { + return offset = 359; + } + + virtual unsigned int offset360(int) { + return offset = 360; + } + + virtual unsigned int offset361(int) { + return offset = 361; + } + + virtual unsigned int offset362(int) { + return offset = 362; + } + + virtual unsigned int offset363(int) { + return offset = 363; + } + + virtual unsigned int offset364(int) { + return offset = 364; + } + + virtual unsigned int offset365(int) { + return offset = 365; + } + + virtual unsigned int offset366(int) { + return offset = 366; + } + + virtual unsigned int offset367(int) { + return offset = 367; + } + + virtual unsigned int offset368(int) { + return offset = 368; + } + + virtual unsigned int offset369(int) { + return offset = 369; + } + + virtual unsigned int offset370(int) { + return offset = 370; + } + + virtual unsigned int offset371(int) { + return offset = 371; + } + + virtual unsigned int offset372(int) { + return offset = 372; + } + + virtual unsigned int offset373(int) { + return offset = 373; + } + + virtual unsigned int offset374(int) { + return offset = 374; + } + + virtual unsigned int offset375(int) { + return offset = 375; + } + + virtual unsigned int offset376(int) { + return offset = 376; + } + + virtual unsigned int offset377(int) { + return offset = 377; + } + + virtual unsigned int offset378(int) { + return offset = 378; + } + + virtual unsigned int offset379(int) { + return offset = 379; + } + + virtual unsigned int offset380(int) { + return offset = 380; + } + + virtual unsigned int offset381(int) { + return offset = 381; + } + + virtual unsigned int offset382(int) { + return offset = 382; + } + + virtual unsigned int offset383(int) { + return offset = 383; + } + + virtual unsigned int offset384(int) { + return offset = 384; + } + + virtual unsigned int offset385(int) { + return offset = 385; + } + + virtual unsigned int offset386(int) { + return offset = 386; + } + + virtual unsigned int offset387(int) { + return offset = 387; + } + + virtual unsigned int offset388(int) { + return offset = 388; + } + + virtual unsigned int offset389(int) { + return offset = 389; + } + + virtual unsigned int offset390(int) { + return offset = 390; + } + + virtual unsigned int offset391(int) { + return offset = 391; + } + + virtual unsigned int offset392(int) { + return offset = 392; + } + + virtual unsigned int offset393(int) { + return offset = 393; + } + + virtual unsigned int offset394(int) { + return offset = 394; + } + + virtual unsigned int offset395(int) { + return offset = 395; + } + + virtual unsigned int offset396(int) { + return offset = 396; + } + + virtual unsigned int offset397(int) { + return offset = 397; + } + + virtual unsigned int offset398(int) { + return offset = 398; + } + + virtual unsigned int offset399(int) { + return offset = 399; + } + + + virtual unsigned int offset400(int) { + return offset = 400; + } + + virtual unsigned int offset401(int) { + return offset = 401; + } + + virtual unsigned int offset402(int) { + return offset = 402; + } + + virtual unsigned int offset403(int) { + return offset = 403; + } + + virtual unsigned int offset404(int) { + return offset = 404; + } + + virtual unsigned int offset405(int) { + return offset = 405; + } + + virtual unsigned int offset406(int) { + return offset = 406; + } + + virtual unsigned int offset407(int) { + return offset = 407; + } + + virtual unsigned int offset408(int) { + return offset = 408; + } + + virtual unsigned int offset409(int) { + return offset = 409; + } + + virtual unsigned int offset410(int) { + return offset = 410; + } + + virtual unsigned int offset411(int) { + return offset = 411; + } + + virtual unsigned int offset412(int) { + return offset = 412; + } + + virtual unsigned int offset413(int) { + return offset = 413; + } + + virtual unsigned int offset414(int) { + return offset = 414; + } + + virtual unsigned int offset415(int) { + return offset = 415; + } + + virtual unsigned int offset416(int) { + return offset = 416; + } + + virtual unsigned int offset417(int) { + return offset = 417; + } + + virtual unsigned int offset418(int) { + return offset = 418; + } + + virtual unsigned int offset419(int) { + return offset = 419; + } + + virtual unsigned int offset420(int) { + return offset = 420; + } + + virtual unsigned int offset421(int) { + return offset = 421; + } + + virtual unsigned int offset422(int) { + return offset = 422; + } + + virtual unsigned int offset423(int) { + return offset = 423; + } + + virtual unsigned int offset424(int) { + return offset = 424; + } + + virtual unsigned int offset425(int) { + return offset = 425; + } + + virtual unsigned int offset426(int) { + return offset = 426; + } + + virtual unsigned int offset427(int) { + return offset = 427; + } + + virtual unsigned int offset428(int) { + return offset = 428; + } + + virtual unsigned int offset429(int) { + return offset = 429; + } + + virtual unsigned int offset430(int) { + return offset = 430; + } + + virtual unsigned int offset431(int) { + return offset = 431; + } + + virtual unsigned int offset432(int) { + return offset = 432; + } + + virtual unsigned int offset433(int) { + return offset = 433; + } + + virtual unsigned int offset434(int) { + return offset = 434; + } + + virtual unsigned int offset435(int) { + return offset = 435; + } + + virtual unsigned int offset436(int) { + return offset = 436; + } + + virtual unsigned int offset437(int) { + return offset = 437; + } + + virtual unsigned int offset438(int) { + return offset = 438; + } + + virtual unsigned int offset439(int) { + return offset = 439; + } + + virtual unsigned int offset440(int) { + return offset = 440; + } + + virtual unsigned int offset441(int) { + return offset = 441; + } + + virtual unsigned int offset442(int) { + return offset = 442; + } + + virtual unsigned int offset443(int) { + return offset = 443; + } + + virtual unsigned int offset444(int) { + return offset = 444; + } + + virtual unsigned int offset445(int) { + return offset = 445; + } + + virtual unsigned int offset446(int) { + return offset = 446; + } + + virtual unsigned int offset447(int) { + return offset = 447; + } + + virtual unsigned int offset448(int) { + return offset = 448; + } + + virtual unsigned int offset449(int) { + return offset = 449; + } + + virtual unsigned int offset450(int) { + return offset = 450; + } + + virtual unsigned int offset451(int) { + return offset = 451; + } + + virtual unsigned int offset452(int) { + return offset = 452; + } + + virtual unsigned int offset453(int) { + return offset = 453; + } + + virtual unsigned int offset454(int) { + return offset = 454; + } + + virtual unsigned int offset455(int) { + return offset = 455; + } + + virtual unsigned int offset456(int) { + return offset = 456; + } + + virtual unsigned int offset457(int) { + return offset = 457; + } + + virtual unsigned int offset458(int) { + return offset = 458; + } + + virtual unsigned int offset459(int) { + return offset = 459; + } + + virtual unsigned int offset460(int) { + return offset = 460; + } + + virtual unsigned int offset461(int) { + return offset = 461; + } + + virtual unsigned int offset462(int) { + return offset = 462; + } + + virtual unsigned int offset463(int) { + return offset = 463; + } + + virtual unsigned int offset464(int) { + return offset = 464; + } + + virtual unsigned int offset465(int) { + return offset = 465; + } + + virtual unsigned int offset466(int) { + return offset = 466; + } + + virtual unsigned int offset467(int) { + return offset = 467; + } + + virtual unsigned int offset468(int) { + return offset = 468; + } + + virtual unsigned int offset469(int) { + return offset = 469; + } + + virtual unsigned int offset470(int) { + return offset = 470; + } + + virtual unsigned int offset471(int) { + return offset = 471; + } + + virtual unsigned int offset472(int) { + return offset = 472; + } + + virtual unsigned int offset473(int) { + return offset = 473; + } + + virtual unsigned int offset474(int) { + return offset = 474; + } + + virtual unsigned int offset475(int) { + return offset = 475; + } + + virtual unsigned int offset476(int) { + return offset = 476; + } + + virtual unsigned int offset477(int) { + return offset = 477; + } + + virtual unsigned int offset478(int) { + return offset = 478; + } + + virtual unsigned int offset479(int) { + return offset = 479; + } + + virtual unsigned int offset480(int) { + return offset = 480; + } + + virtual unsigned int offset481(int) { + return offset = 481; + } + + virtual unsigned int offset482(int) { + return offset = 482; + } + + virtual unsigned int offset483(int) { + return offset = 483; + } + + virtual unsigned int offset484(int) { + return offset = 484; + } + + virtual unsigned int offset485(int) { + return offset = 485; + } + + virtual unsigned int offset486(int) { + return offset = 486; + } + + virtual unsigned int offset487(int) { + return offset = 487; + } + + virtual unsigned int offset488(int) { + return offset = 488; + } + + virtual unsigned int offset489(int) { + return offset = 489; + } + + virtual unsigned int offset490(int) { + return offset = 490; + } + + virtual unsigned int offset491(int) { + return offset = 491; + } + + virtual unsigned int offset492(int) { + return offset = 492; + } + + virtual unsigned int offset493(int) { + return offset = 493; + } + + virtual unsigned int offset494(int) { + return offset = 494; + } + + virtual unsigned int offset495(int) { + return offset = 495; + } + + virtual unsigned int offset496(int) { + return offset = 496; + } + + virtual unsigned int offset497(int) { + return offset = 497; + } + + virtual unsigned int offset498(int) { + return offset = 498; + } + + virtual unsigned int offset499(int) { + return offset = 499; + } + + + virtual unsigned int offset500(int) { + return offset = 500; + } + + virtual unsigned int offset501(int) { + return offset = 501; + } + + virtual unsigned int offset502(int) { + return offset = 502; + } + + virtual unsigned int offset503(int) { + return offset = 503; + } + + virtual unsigned int offset504(int) { + return offset = 504; + } + + virtual unsigned int offset505(int) { + return offset = 505; + } + + virtual unsigned int offset506(int) { + return offset = 506; + } + + virtual unsigned int offset507(int) { + return offset = 507; + } + + virtual unsigned int offset508(int) { + return offset = 508; + } + + virtual unsigned int offset509(int) { + return offset = 509; + } + + virtual unsigned int offset510(int) { + return offset = 510; + } + + virtual unsigned int offset511(int) { + return offset = 511; + } + + virtual unsigned int offset512(int) { + return offset = 512; + } + + virtual unsigned int offset513(int) { + return offset = 513; + } + + virtual unsigned int offset514(int) { + return offset = 514; + } + + virtual unsigned int offset515(int) { + return offset = 515; + } + + virtual unsigned int offset516(int) { + return offset = 516; + } + + virtual unsigned int offset517(int) { + return offset = 517; + } + + virtual unsigned int offset518(int) { + return offset = 518; + } + + virtual unsigned int offset519(int) { + return offset = 519; + } + + virtual unsigned int offset520(int) { + return offset = 520; + } + + virtual unsigned int offset521(int) { + return offset = 521; + } + + virtual unsigned int offset522(int) { + return offset = 522; + } + + virtual unsigned int offset523(int) { + return offset = 523; + } + + virtual unsigned int offset524(int) { + return offset = 524; + } + + virtual unsigned int offset525(int) { + return offset = 525; + } + + virtual unsigned int offset526(int) { + return offset = 526; + } + + virtual unsigned int offset527(int) { + return offset = 527; + } + + virtual unsigned int offset528(int) { + return offset = 528; + } + + virtual unsigned int offset529(int) { + return offset = 529; + } + + virtual unsigned int offset530(int) { + return offset = 530; + } + + virtual unsigned int offset531(int) { + return offset = 531; + } + + virtual unsigned int offset532(int) { + return offset = 532; + } + + virtual unsigned int offset533(int) { + return offset = 533; + } + + virtual unsigned int offset534(int) { + return offset = 534; + } + + virtual unsigned int offset535(int) { + return offset = 535; + } + + virtual unsigned int offset536(int) { + return offset = 536; + } + + virtual unsigned int offset537(int) { + return offset = 537; + } + + virtual unsigned int offset538(int) { + return offset = 538; + } + + virtual unsigned int offset539(int) { + return offset = 539; + } + + virtual unsigned int offset540(int) { + return offset = 540; + } + + virtual unsigned int offset541(int) { + return offset = 541; + } + + virtual unsigned int offset542(int) { + return offset = 542; + } + + virtual unsigned int offset543(int) { + return offset = 543; + } + + virtual unsigned int offset544(int) { + return offset = 544; + } + + virtual unsigned int offset545(int) { + return offset = 545; + } + + virtual unsigned int offset546(int) { + return offset = 546; + } + + virtual unsigned int offset547(int) { + return offset = 547; + } + + virtual unsigned int offset548(int) { + return offset = 548; + } + + virtual unsigned int offset549(int) { + return offset = 549; + } + + virtual unsigned int offset550(int) { + return offset = 550; + } + + virtual unsigned int offset551(int) { + return offset = 551; + } + + virtual unsigned int offset552(int) { + return offset = 552; + } + + virtual unsigned int offset553(int) { + return offset = 553; + } + + virtual unsigned int offset554(int) { + return offset = 554; + } + + virtual unsigned int offset555(int) { + return offset = 555; + } + + virtual unsigned int offset556(int) { + return offset = 556; + } + + virtual unsigned int offset557(int) { + return offset = 557; + } + + virtual unsigned int offset558(int) { + return offset = 558; + } + + virtual unsigned int offset559(int) { + return offset = 559; + } + + virtual unsigned int offset560(int) { + return offset = 560; + } + + virtual unsigned int offset561(int) { + return offset = 561; + } + + virtual unsigned int offset562(int) { + return offset = 562; + } + + virtual unsigned int offset563(int) { + return offset = 563; + } + + virtual unsigned int offset564(int) { + return offset = 564; + } + + virtual unsigned int offset565(int) { + return offset = 565; + } + + virtual unsigned int offset566(int) { + return offset = 566; + } + + virtual unsigned int offset567(int) { + return offset = 567; + } + + virtual unsigned int offset568(int) { + return offset = 568; + } + + virtual unsigned int offset569(int) { + return offset = 569; + } + + virtual unsigned int offset570(int) { + return offset = 570; + } + + virtual unsigned int offset571(int) { + return offset = 571; + } + + virtual unsigned int offset572(int) { + return offset = 572; + } + + virtual unsigned int offset573(int) { + return offset = 573; + } + + virtual unsigned int offset574(int) { + return offset = 574; + } + + virtual unsigned int offset575(int) { + return offset = 575; + } + + virtual unsigned int offset576(int) { + return offset = 576; + } + + virtual unsigned int offset577(int) { + return offset = 577; + } + + virtual unsigned int offset578(int) { + return offset = 578; + } + + virtual unsigned int offset579(int) { + return offset = 579; + } + + virtual unsigned int offset580(int) { + return offset = 580; + } + + virtual unsigned int offset581(int) { + return offset = 581; + } + + virtual unsigned int offset582(int) { + return offset = 582; + } + + virtual unsigned int offset583(int) { + return offset = 583; + } + + virtual unsigned int offset584(int) { + return offset = 584; + } + + virtual unsigned int offset585(int) { + return offset = 585; + } + + virtual unsigned int offset586(int) { + return offset = 586; + } + + virtual unsigned int offset587(int) { + return offset = 587; + } + + virtual unsigned int offset588(int) { + return offset = 588; + } + + virtual unsigned int offset589(int) { + return offset = 589; + } + + virtual unsigned int offset590(int) { + return offset = 590; + } + + virtual unsigned int offset591(int) { + return offset = 591; + } + + virtual unsigned int offset592(int) { + return offset = 592; + } + + virtual unsigned int offset593(int) { + return offset = 593; + } + + virtual unsigned int offset594(int) { + return offset = 594; + } + + virtual unsigned int offset595(int) { + return offset = 595; + } + + virtual unsigned int offset596(int) { + return offset = 596; + } + + virtual unsigned int offset597(int) { + return offset = 597; + } + + virtual unsigned int offset598(int) { + return offset = 598; + } + + virtual unsigned int offset599(int) { + return offset = 599; + } + + + virtual unsigned int offset600(int) { + return offset = 600; + } + + virtual unsigned int offset601(int) { + return offset = 601; + } + + virtual unsigned int offset602(int) { + return offset = 602; + } + + virtual unsigned int offset603(int) { + return offset = 603; + } + + virtual unsigned int offset604(int) { + return offset = 604; + } + + virtual unsigned int offset605(int) { + return offset = 605; + } + + virtual unsigned int offset606(int) { + return offset = 606; + } + + virtual unsigned int offset607(int) { + return offset = 607; + } + + virtual unsigned int offset608(int) { + return offset = 608; + } + + virtual unsigned int offset609(int) { + return offset = 609; + } + + virtual unsigned int offset610(int) { + return offset = 610; + } + + virtual unsigned int offset611(int) { + return offset = 611; + } + + virtual unsigned int offset612(int) { + return offset = 612; + } + + virtual unsigned int offset613(int) { + return offset = 613; + } + + virtual unsigned int offset614(int) { + return offset = 614; + } + + virtual unsigned int offset615(int) { + return offset = 615; + } + + virtual unsigned int offset616(int) { + return offset = 616; + } + + virtual unsigned int offset617(int) { + return offset = 617; + } + + virtual unsigned int offset618(int) { + return offset = 618; + } + + virtual unsigned int offset619(int) { + return offset = 619; + } + + virtual unsigned int offset620(int) { + return offset = 620; + } + + virtual unsigned int offset621(int) { + return offset = 621; + } + + virtual unsigned int offset622(int) { + return offset = 622; + } + + virtual unsigned int offset623(int) { + return offset = 623; + } + + virtual unsigned int offset624(int) { + return offset = 624; + } + + virtual unsigned int offset625(int) { + return offset = 625; + } + + virtual unsigned int offset626(int) { + return offset = 626; + } + + virtual unsigned int offset627(int) { + return offset = 627; + } + + virtual unsigned int offset628(int) { + return offset = 628; + } + + virtual unsigned int offset629(int) { + return offset = 629; + } + + virtual unsigned int offset630(int) { + return offset = 630; + } + + virtual unsigned int offset631(int) { + return offset = 631; + } + + virtual unsigned int offset632(int) { + return offset = 632; + } + + virtual unsigned int offset633(int) { + return offset = 633; + } + + virtual unsigned int offset634(int) { + return offset = 634; + } + + virtual unsigned int offset635(int) { + return offset = 635; + } + + virtual unsigned int offset636(int) { + return offset = 636; + } + + virtual unsigned int offset637(int) { + return offset = 637; + } + + virtual unsigned int offset638(int) { + return offset = 638; + } + + virtual unsigned int offset639(int) { + return offset = 639; + } + + virtual unsigned int offset640(int) { + return offset = 640; + } + + virtual unsigned int offset641(int) { + return offset = 641; + } + + virtual unsigned int offset642(int) { + return offset = 642; + } + + virtual unsigned int offset643(int) { + return offset = 643; + } + + virtual unsigned int offset644(int) { + return offset = 644; + } + + virtual unsigned int offset645(int) { + return offset = 645; + } + + virtual unsigned int offset646(int) { + return offset = 646; + } + + virtual unsigned int offset647(int) { + return offset = 647; + } + + virtual unsigned int offset648(int) { + return offset = 648; + } + + virtual unsigned int offset649(int) { + return offset = 649; + } + + virtual unsigned int offset650(int) { + return offset = 650; + } + + virtual unsigned int offset651(int) { + return offset = 651; + } + + virtual unsigned int offset652(int) { + return offset = 652; + } + + virtual unsigned int offset653(int) { + return offset = 653; + } + + virtual unsigned int offset654(int) { + return offset = 654; + } + + virtual unsigned int offset655(int) { + return offset = 655; + } + + virtual unsigned int offset656(int) { + return offset = 656; + } + + virtual unsigned int offset657(int) { + return offset = 657; + } + + virtual unsigned int offset658(int) { + return offset = 658; + } + + virtual unsigned int offset659(int) { + return offset = 659; + } + + virtual unsigned int offset660(int) { + return offset = 660; + } + + virtual unsigned int offset661(int) { + return offset = 661; + } + + virtual unsigned int offset662(int) { + return offset = 662; + } + + virtual unsigned int offset663(int) { + return offset = 663; + } + + virtual unsigned int offset664(int) { + return offset = 664; + } + + virtual unsigned int offset665(int) { + return offset = 665; + } + + virtual unsigned int offset666(int) { + return offset = 666; + } + + virtual unsigned int offset667(int) { + return offset = 667; + } + + virtual unsigned int offset668(int) { + return offset = 668; + } + + virtual unsigned int offset669(int) { + return offset = 669; + } + + virtual unsigned int offset670(int) { + return offset = 670; + } + + virtual unsigned int offset671(int) { + return offset = 671; + } + + virtual unsigned int offset672(int) { + return offset = 672; + } + + virtual unsigned int offset673(int) { + return offset = 673; + } + + virtual unsigned int offset674(int) { + return offset = 674; + } + + virtual unsigned int offset675(int) { + return offset = 675; + } + + virtual unsigned int offset676(int) { + return offset = 676; + } + + virtual unsigned int offset677(int) { + return offset = 677; + } + + virtual unsigned int offset678(int) { + return offset = 678; + } + + virtual unsigned int offset679(int) { + return offset = 679; + } + + virtual unsigned int offset680(int) { + return offset = 680; + } + + virtual unsigned int offset681(int) { + return offset = 681; + } + + virtual unsigned int offset682(int) { + return offset = 682; + } + + virtual unsigned int offset683(int) { + return offset = 683; + } + + virtual unsigned int offset684(int) { + return offset = 684; + } + + virtual unsigned int offset685(int) { + return offset = 685; + } + + virtual unsigned int offset686(int) { + return offset = 686; + } + + virtual unsigned int offset687(int) { + return offset = 687; + } + + virtual unsigned int offset688(int) { + return offset = 688; + } + + virtual unsigned int offset689(int) { + return offset = 689; + } + + virtual unsigned int offset690(int) { + return offset = 690; + } + + virtual unsigned int offset691(int) { + return offset = 691; + } + + virtual unsigned int offset692(int) { + return offset = 692; + } + + virtual unsigned int offset693(int) { + return offset = 693; + } + + virtual unsigned int offset694(int) { + return offset = 694; + } + + virtual unsigned int offset695(int) { + return offset = 695; + } + + virtual unsigned int offset696(int) { + return offset = 696; + } + + virtual unsigned int offset697(int) { + return offset = 697; + } + + virtual unsigned int offset698(int) { + return offset = 698; + } + + virtual unsigned int offset699(int) { + return offset = 699; + } + + + virtual unsigned int offset700(int) { + return offset = 700; + } + + virtual unsigned int offset701(int) { + return offset = 701; + } + + virtual unsigned int offset702(int) { + return offset = 702; + } + + virtual unsigned int offset703(int) { + return offset = 703; + } + + virtual unsigned int offset704(int) { + return offset = 704; + } + + virtual unsigned int offset705(int) { + return offset = 705; + } + + virtual unsigned int offset706(int) { + return offset = 706; + } + + virtual unsigned int offset707(int) { + return offset = 707; + } + + virtual unsigned int offset708(int) { + return offset = 708; + } + + virtual unsigned int offset709(int) { + return offset = 709; + } + + virtual unsigned int offset710(int) { + return offset = 710; + } + + virtual unsigned int offset711(int) { + return offset = 711; + } + + virtual unsigned int offset712(int) { + return offset = 712; + } + + virtual unsigned int offset713(int) { + return offset = 713; + } + + virtual unsigned int offset714(int) { + return offset = 714; + } + + virtual unsigned int offset715(int) { + return offset = 715; + } + + virtual unsigned int offset716(int) { + return offset = 716; + } + + virtual unsigned int offset717(int) { + return offset = 717; + } + + virtual unsigned int offset718(int) { + return offset = 718; + } + + virtual unsigned int offset719(int) { + return offset = 719; + } + + virtual unsigned int offset720(int) { + return offset = 720; + } + + virtual unsigned int offset721(int) { + return offset = 721; + } + + virtual unsigned int offset722(int) { + return offset = 722; + } + + virtual unsigned int offset723(int) { + return offset = 723; + } + + virtual unsigned int offset724(int) { + return offset = 724; + } + + virtual unsigned int offset725(int) { + return offset = 725; + } + + virtual unsigned int offset726(int) { + return offset = 726; + } + + virtual unsigned int offset727(int) { + return offset = 727; + } + + virtual unsigned int offset728(int) { + return offset = 728; + } + + virtual unsigned int offset729(int) { + return offset = 729; + } + + virtual unsigned int offset730(int) { + return offset = 730; + } + + virtual unsigned int offset731(int) { + return offset = 731; + } + + virtual unsigned int offset732(int) { + return offset = 732; + } + + virtual unsigned int offset733(int) { + return offset = 733; + } + + virtual unsigned int offset734(int) { + return offset = 734; + } + + virtual unsigned int offset735(int) { + return offset = 735; + } + + virtual unsigned int offset736(int) { + return offset = 736; + } + + virtual unsigned int offset737(int) { + return offset = 737; + } + + virtual unsigned int offset738(int) { + return offset = 738; + } + + virtual unsigned int offset739(int) { + return offset = 739; + } + + virtual unsigned int offset740(int) { + return offset = 740; + } + + virtual unsigned int offset741(int) { + return offset = 741; + } + + virtual unsigned int offset742(int) { + return offset = 742; + } + + virtual unsigned int offset743(int) { + return offset = 743; + } + + virtual unsigned int offset744(int) { + return offset = 744; + } + + virtual unsigned int offset745(int) { + return offset = 745; + } + + virtual unsigned int offset746(int) { + return offset = 746; + } + + virtual unsigned int offset747(int) { + return offset = 747; + } + + virtual unsigned int offset748(int) { + return offset = 748; + } + + virtual unsigned int offset749(int) { + return offset = 749; + } + + virtual unsigned int offset750(int) { + return offset = 750; + } + + virtual unsigned int offset751(int) { + return offset = 751; + } + + virtual unsigned int offset752(int) { + return offset = 752; + } + + virtual unsigned int offset753(int) { + return offset = 753; + } + + virtual unsigned int offset754(int) { + return offset = 754; + } + + virtual unsigned int offset755(int) { + return offset = 755; + } + + virtual unsigned int offset756(int) { + return offset = 756; + } + + virtual unsigned int offset757(int) { + return offset = 757; + } + + virtual unsigned int offset758(int) { + return offset = 758; + } + + virtual unsigned int offset759(int) { + return offset = 759; + } + + virtual unsigned int offset760(int) { + return offset = 760; + } + + virtual unsigned int offset761(int) { + return offset = 761; + } + + virtual unsigned int offset762(int) { + return offset = 762; + } + + virtual unsigned int offset763(int) { + return offset = 763; + } + + virtual unsigned int offset764(int) { + return offset = 764; + } + + virtual unsigned int offset765(int) { + return offset = 765; + } + + virtual unsigned int offset766(int) { + return offset = 766; + } + + virtual unsigned int offset767(int) { + return offset = 767; + } + + virtual unsigned int offset768(int) { + return offset = 768; + } + + virtual unsigned int offset769(int) { + return offset = 769; + } + + virtual unsigned int offset770(int) { + return offset = 770; + } + + virtual unsigned int offset771(int) { + return offset = 771; + } + + virtual unsigned int offset772(int) { + return offset = 772; + } + + virtual unsigned int offset773(int) { + return offset = 773; + } + + virtual unsigned int offset774(int) { + return offset = 774; + } + + virtual unsigned int offset775(int) { + return offset = 775; + } + + virtual unsigned int offset776(int) { + return offset = 776; + } + + virtual unsigned int offset777(int) { + return offset = 777; + } + + virtual unsigned int offset778(int) { + return offset = 778; + } + + virtual unsigned int offset779(int) { + return offset = 779; + } + + virtual unsigned int offset780(int) { + return offset = 780; + } + + virtual unsigned int offset781(int) { + return offset = 781; + } + + virtual unsigned int offset782(int) { + return offset = 782; + } + + virtual unsigned int offset783(int) { + return offset = 783; + } + + virtual unsigned int offset784(int) { + return offset = 784; + } + + virtual unsigned int offset785(int) { + return offset = 785; + } + + virtual unsigned int offset786(int) { + return offset = 786; + } + + virtual unsigned int offset787(int) { + return offset = 787; + } + + virtual unsigned int offset788(int) { + return offset = 788; + } + + virtual unsigned int offset789(int) { + return offset = 789; + } + + virtual unsigned int offset790(int) { + return offset = 790; + } + + virtual unsigned int offset791(int) { + return offset = 791; + } + + virtual unsigned int offset792(int) { + return offset = 792; + } + + virtual unsigned int offset793(int) { + return offset = 793; + } + + virtual unsigned int offset794(int) { + return offset = 794; + } + + virtual unsigned int offset795(int) { + return offset = 795; + } + + virtual unsigned int offset796(int) { + return offset = 796; + } + + virtual unsigned int offset797(int) { + return offset = 797; + } + + virtual unsigned int offset798(int) { + return offset = 798; + } + + virtual unsigned int offset799(int) { + return offset = 799; + } + + + virtual unsigned int offset800(int) { + return offset = 800; + } + + virtual unsigned int offset801(int) { + return offset = 801; + } + + virtual unsigned int offset802(int) { + return offset = 802; + } + + virtual unsigned int offset803(int) { + return offset = 803; + } + + virtual unsigned int offset804(int) { + return offset = 804; + } + + virtual unsigned int offset805(int) { + return offset = 805; + } + + virtual unsigned int offset806(int) { + return offset = 806; + } + + virtual unsigned int offset807(int) { + return offset = 807; + } + + virtual unsigned int offset808(int) { + return offset = 808; + } + + virtual unsigned int offset809(int) { + return offset = 809; + } + + virtual unsigned int offset810(int) { + return offset = 810; + } + + virtual unsigned int offset811(int) { + return offset = 811; + } + + virtual unsigned int offset812(int) { + return offset = 812; + } + + virtual unsigned int offset813(int) { + return offset = 813; + } + + virtual unsigned int offset814(int) { + return offset = 814; + } + + virtual unsigned int offset815(int) { + return offset = 815; + } + + virtual unsigned int offset816(int) { + return offset = 816; + } + + virtual unsigned int offset817(int) { + return offset = 817; + } + + virtual unsigned int offset818(int) { + return offset = 818; + } + + virtual unsigned int offset819(int) { + return offset = 819; + } + + virtual unsigned int offset820(int) { + return offset = 820; + } + + virtual unsigned int offset821(int) { + return offset = 821; + } + + virtual unsigned int offset822(int) { + return offset = 822; + } + + virtual unsigned int offset823(int) { + return offset = 823; + } + + virtual unsigned int offset824(int) { + return offset = 824; + } + + virtual unsigned int offset825(int) { + return offset = 825; + } + + virtual unsigned int offset826(int) { + return offset = 826; + } + + virtual unsigned int offset827(int) { + return offset = 827; + } + + virtual unsigned int offset828(int) { + return offset = 828; + } + + virtual unsigned int offset829(int) { + return offset = 829; + } + + virtual unsigned int offset830(int) { + return offset = 830; + } + + virtual unsigned int offset831(int) { + return offset = 831; + } + + virtual unsigned int offset832(int) { + return offset = 832; + } + + virtual unsigned int offset833(int) { + return offset = 833; + } + + virtual unsigned int offset834(int) { + return offset = 834; + } + + virtual unsigned int offset835(int) { + return offset = 835; + } + + virtual unsigned int offset836(int) { + return offset = 836; + } + + virtual unsigned int offset837(int) { + return offset = 837; + } + + virtual unsigned int offset838(int) { + return offset = 838; + } + + virtual unsigned int offset839(int) { + return offset = 839; + } + + virtual unsigned int offset840(int) { + return offset = 840; + } + + virtual unsigned int offset841(int) { + return offset = 841; + } + + virtual unsigned int offset842(int) { + return offset = 842; + } + + virtual unsigned int offset843(int) { + return offset = 843; + } + + virtual unsigned int offset844(int) { + return offset = 844; + } + + virtual unsigned int offset845(int) { + return offset = 845; + } + + virtual unsigned int offset846(int) { + return offset = 846; + } + + virtual unsigned int offset847(int) { + return offset = 847; + } + + virtual unsigned int offset848(int) { + return offset = 848; + } + + virtual unsigned int offset849(int) { + return offset = 849; + } + + virtual unsigned int offset850(int) { + return offset = 850; + } + + virtual unsigned int offset851(int) { + return offset = 851; + } + + virtual unsigned int offset852(int) { + return offset = 852; + } + + virtual unsigned int offset853(int) { + return offset = 853; + } + + virtual unsigned int offset854(int) { + return offset = 854; + } + + virtual unsigned int offset855(int) { + return offset = 855; + } + + virtual unsigned int offset856(int) { + return offset = 856; + } + + virtual unsigned int offset857(int) { + return offset = 857; + } + + virtual unsigned int offset858(int) { + return offset = 858; + } + + virtual unsigned int offset859(int) { + return offset = 859; + } + + virtual unsigned int offset860(int) { + return offset = 860; + } + + virtual unsigned int offset861(int) { + return offset = 861; + } + + virtual unsigned int offset862(int) { + return offset = 862; + } + + virtual unsigned int offset863(int) { + return offset = 863; + } + + virtual unsigned int offset864(int) { + return offset = 864; + } + + virtual unsigned int offset865(int) { + return offset = 865; + } + + virtual unsigned int offset866(int) { + return offset = 866; + } + + virtual unsigned int offset867(int) { + return offset = 867; + } + + virtual unsigned int offset868(int) { + return offset = 868; + } + + virtual unsigned int offset869(int) { + return offset = 869; + } + + virtual unsigned int offset870(int) { + return offset = 870; + } + + virtual unsigned int offset871(int) { + return offset = 871; + } + + virtual unsigned int offset872(int) { + return offset = 872; + } + + virtual unsigned int offset873(int) { + return offset = 873; + } + + virtual unsigned int offset874(int) { + return offset = 874; + } + + virtual unsigned int offset875(int) { + return offset = 875; + } + + virtual unsigned int offset876(int) { + return offset = 876; + } + + virtual unsigned int offset877(int) { + return offset = 877; + } + + virtual unsigned int offset878(int) { + return offset = 878; + } + + virtual unsigned int offset879(int) { + return offset = 879; + } + + virtual unsigned int offset880(int) { + return offset = 880; + } + + virtual unsigned int offset881(int) { + return offset = 881; + } + + virtual unsigned int offset882(int) { + return offset = 882; + } + + virtual unsigned int offset883(int) { + return offset = 883; + } + + virtual unsigned int offset884(int) { + return offset = 884; + } + + virtual unsigned int offset885(int) { + return offset = 885; + } + + virtual unsigned int offset886(int) { + return offset = 886; + } + + virtual unsigned int offset887(int) { + return offset = 887; + } + + virtual unsigned int offset888(int) { + return offset = 888; + } + + virtual unsigned int offset889(int) { + return offset = 889; + } + + virtual unsigned int offset890(int) { + return offset = 890; + } + + virtual unsigned int offset891(int) { + return offset = 891; + } + + virtual unsigned int offset892(int) { + return offset = 892; + } + + virtual unsigned int offset893(int) { + return offset = 893; + } + + virtual unsigned int offset894(int) { + return offset = 894; + } + + virtual unsigned int offset895(int) { + return offset = 895; + } + + virtual unsigned int offset896(int) { + return offset = 896; + } + + virtual unsigned int offset897(int) { + return offset = 897; + } + + virtual unsigned int offset898(int) { + return offset = 898; + } + + virtual unsigned int offset899(int) { + return offset = 899; + } + + + virtual unsigned int offset900(int) { + return offset = 900; + } + + virtual unsigned int offset901(int) { + return offset = 901; + } + + virtual unsigned int offset902(int) { + return offset = 902; + } + + virtual unsigned int offset903(int) { + return offset = 903; + } + + virtual unsigned int offset904(int) { + return offset = 904; + } + + virtual unsigned int offset905(int) { + return offset = 905; + } + + virtual unsigned int offset906(int) { + return offset = 906; + } + + virtual unsigned int offset907(int) { + return offset = 907; + } + + virtual unsigned int offset908(int) { + return offset = 908; + } + + virtual unsigned int offset909(int) { + return offset = 909; + } + + virtual unsigned int offset910(int) { + return offset = 910; + } + + virtual unsigned int offset911(int) { + return offset = 911; + } + + virtual unsigned int offset912(int) { + return offset = 912; + } + + virtual unsigned int offset913(int) { + return offset = 913; + } + + virtual unsigned int offset914(int) { + return offset = 914; + } + + virtual unsigned int offset915(int) { + return offset = 915; + } + + virtual unsigned int offset916(int) { + return offset = 916; + } + + virtual unsigned int offset917(int) { + return offset = 917; + } + + virtual unsigned int offset918(int) { + return offset = 918; + } + + virtual unsigned int offset919(int) { + return offset = 919; + } + + virtual unsigned int offset920(int) { + return offset = 920; + } + + virtual unsigned int offset921(int) { + return offset = 921; + } + + virtual unsigned int offset922(int) { + return offset = 922; + } + + virtual unsigned int offset923(int) { + return offset = 923; + } + + virtual unsigned int offset924(int) { + return offset = 924; + } + + virtual unsigned int offset925(int) { + return offset = 925; + } + + virtual unsigned int offset926(int) { + return offset = 926; + } + + virtual unsigned int offset927(int) { + return offset = 927; + } + + virtual unsigned int offset928(int) { + return offset = 928; + } + + virtual unsigned int offset929(int) { + return offset = 929; + } + + virtual unsigned int offset930(int) { + return offset = 930; + } + + virtual unsigned int offset931(int) { + return offset = 931; + } + + virtual unsigned int offset932(int) { + return offset = 932; + } + + virtual unsigned int offset933(int) { + return offset = 933; + } + + virtual unsigned int offset934(int) { + return offset = 934; + } + + virtual unsigned int offset935(int) { + return offset = 935; + } + + virtual unsigned int offset936(int) { + return offset = 936; + } + + virtual unsigned int offset937(int) { + return offset = 937; + } + + virtual unsigned int offset938(int) { + return offset = 938; + } + + virtual unsigned int offset939(int) { + return offset = 939; + } + + virtual unsigned int offset940(int) { + return offset = 940; + } + + virtual unsigned int offset941(int) { + return offset = 941; + } + + virtual unsigned int offset942(int) { + return offset = 942; + } + + virtual unsigned int offset943(int) { + return offset = 943; + } + + virtual unsigned int offset944(int) { + return offset = 944; + } + + virtual unsigned int offset945(int) { + return offset = 945; + } + + virtual unsigned int offset946(int) { + return offset = 946; + } + + virtual unsigned int offset947(int) { + return offset = 947; + } + + virtual unsigned int offset948(int) { + return offset = 948; + } + + virtual unsigned int offset949(int) { + return offset = 949; + } + + virtual unsigned int offset950(int) { + return offset = 950; + } + + virtual unsigned int offset951(int) { + return offset = 951; + } + + virtual unsigned int offset952(int) { + return offset = 952; + } + + virtual unsigned int offset953(int) { + return offset = 953; + } + + virtual unsigned int offset954(int) { + return offset = 954; + } + + virtual unsigned int offset955(int) { + return offset = 955; + } + + virtual unsigned int offset956(int) { + return offset = 956; + } + + virtual unsigned int offset957(int) { + return offset = 957; + } + + virtual unsigned int offset958(int) { + return offset = 958; + } + + virtual unsigned int offset959(int) { + return offset = 959; + } + + virtual unsigned int offset960(int) { + return offset = 960; + } + + virtual unsigned int offset961(int) { + return offset = 961; + } + + virtual unsigned int offset962(int) { + return offset = 962; + } + + virtual unsigned int offset963(int) { + return offset = 963; + } + + virtual unsigned int offset964(int) { + return offset = 964; + } + + virtual unsigned int offset965(int) { + return offset = 965; + } + + virtual unsigned int offset966(int) { + return offset = 966; + } + + virtual unsigned int offset967(int) { + return offset = 967; + } + + virtual unsigned int offset968(int) { + return offset = 968; + } + + virtual unsigned int offset969(int) { + return offset = 969; + } + + virtual unsigned int offset970(int) { + return offset = 970; + } + + virtual unsigned int offset971(int) { + return offset = 971; + } + + virtual unsigned int offset972(int) { + return offset = 972; + } + + virtual unsigned int offset973(int) { + return offset = 973; + } + + virtual unsigned int offset974(int) { + return offset = 974; + } + + virtual unsigned int offset975(int) { + return offset = 975; + } + + virtual unsigned int offset976(int) { + return offset = 976; + } + + virtual unsigned int offset977(int) { + return offset = 977; + } + + virtual unsigned int offset978(int) { + return offset = 978; + } + + virtual unsigned int offset979(int) { + return offset = 979; + } + + virtual unsigned int offset980(int) { + return offset = 980; + } + + virtual unsigned int offset981(int) { + return offset = 981; + } + + virtual unsigned int offset982(int) { + return offset = 982; + } + + virtual unsigned int offset983(int) { + return offset = 983; + } + + virtual unsigned int offset984(int) { + return offset = 984; + } + + virtual unsigned int offset985(int) { + return offset = 985; + } + + virtual unsigned int offset986(int) { + return offset = 986; + } + + virtual unsigned int offset987(int) { + return offset = 987; + } + + virtual unsigned int offset988(int) { + return offset = 988; + } + + virtual unsigned int offset989(int) { + return offset = 989; + } + + virtual unsigned int offset990(int) { + return offset = 990; + } + + virtual unsigned int offset991(int) { + return offset = 991; + } + + virtual unsigned int offset992(int) { + return offset = 992; + } + + virtual unsigned int offset993(int) { + return offset = 993; + } + + virtual unsigned int offset994(int) { + return offset = 994; + } + + virtual unsigned int offset995(int) { + return offset = 995; + } + + virtual unsigned int offset996(int) { + return offset = 996; + } + + virtual unsigned int offset997(int) { + return offset = 997; + } + + virtual unsigned int offset998(int) { + return offset = 998; + } + + virtual unsigned int offset999(int) { + return offset = 999; + } + + virtual unsigned int offset1000(int) { + return offset = 1000; + } + + virtual ~VirtualOffsetSelector() { } + }; +} +#if defined(__GNUG__) && !defined(__clang__) +#define FAKEIT_NO_DEVIRTUALIZE_ATTR [[gnu::optimize("no-devirtualize")]] +#else +#define FAKEIT_NO_DEVIRTUALIZE_ATTR +#endif + +namespace fakeit { + + template + FAKEIT_NO_DEVIRTUALIZE_ATTR + TargetType union_cast(SourceType source) { + + union { + SourceType source; + TargetType target; + } u; + u.source = source; + return u.target; + } + +} + +namespace fakeit { + class VTUtils { + public: + +#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + template + static unsigned int getOffset(R (C::*vMethod)(arglist...)) { + auto sMethod = reinterpret_cast(vMethod); + VirtualOffsetSelector offsetSelctor; + return (offsetSelctor.*sMethod)(0); + } +#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + + template + FAKEIT_DISARM_UBSAN + static typename std::enable_if::value, unsigned int>::type + getDestructorOffset() { + VirtualOffsetSelector offsetSelctor; + union_cast(&offsetSelctor)->~C(); + return offsetSelctor.offset; + } + + template + static typename std::enable_if::value, unsigned int>::type + getDestructorOffset() { + FAIL("Can't mock the destructor. No virtual destructor was found"); + } + + template + static typename std::enable_if::value, bool>::type + hasVirtualDestructor() { + return true; + } + + template + static typename std::enable_if::value, bool>::type + hasVirtualDestructor() { + return false; + } + + template + static unsigned int getVTSize() { + struct Derrived : public C { + virtual void endOfVt() { + } + }; + + unsigned int vtSize = getOffset(&Derrived::endOfVt); + return vtSize; + } + }; + + +} +#ifdef _MSC_VER +namespace fakeit { + + typedef unsigned long dword_; + + struct TypeDescriptor { + TypeDescriptor() : + ptrToVTable(0), spare(0) { + + int **tiVFTPtr = (int **) (&typeid(void)); + int *i = (int *) tiVFTPtr[0]; + char *type_info_vft_ptr = (char *) i; + ptrToVTable = type_info_vft_ptr; + } + + char *ptrToVTable; + dword_ spare; + char name[8]; + }; + + struct PmdInfo { + + + + int mdisp; + + int pdisp; + int vdisp; + + PmdInfo() : + mdisp(0), pdisp(-1), vdisp(0) { + } + }; + + struct RTTIBaseClassDescriptor { + RTTIBaseClassDescriptor() : + pTypeDescriptor(nullptr), numContainedBases(0), attributes(0) { + } + + const std::type_info *pTypeDescriptor; + dword_ numContainedBases; + struct PmdInfo where; + dword_ attributes; + }; + + template + struct RTTIClassHierarchyDescriptor { + RTTIClassHierarchyDescriptor() : + signature(0), + attributes(0), + numBaseClasses(0), + pBaseClassArray(nullptr) { + pBaseClassArray = new RTTIBaseClassDescriptor *[1 + sizeof...(baseclasses)]; + addBaseClass < C, baseclasses...>(); + } + + ~RTTIClassHierarchyDescriptor() { + for (int i = 0; i < 1 + sizeof...(baseclasses); i++) { + RTTIBaseClassDescriptor *desc = pBaseClassArray[i]; + delete desc; + } + delete[] pBaseClassArray; + } + + dword_ signature; + dword_ attributes; + dword_ numBaseClasses; + RTTIBaseClassDescriptor **pBaseClassArray; + + template + void addBaseClass() { + static_assert(std::is_base_of::value, "C must be a derived class of BaseType"); + RTTIBaseClassDescriptor *desc = new RTTIBaseClassDescriptor(); + desc->pTypeDescriptor = &typeid(BaseType); + pBaseClassArray[numBaseClasses] = desc; + for (unsigned int i = 0; i < numBaseClasses; i++) { + pBaseClassArray[i]->numContainedBases++; + } + numBaseClasses++; + } + + template + void addBaseClass() { + static_assert(std::is_base_of::value, "invalid inheritance list"); + addBaseClass(); + addBaseClass(); + } + + }; + + template + struct RTTICompleteObjectLocator { +#ifdef _WIN64 + RTTICompleteObjectLocator(const std::type_info &unused) : + signature(0), offset(0), cdOffset(0), + typeDescriptorOffset(0), classDescriptorOffset(0) + { + (void)unused; + } + + dword_ signature; + dword_ offset; + dword_ cdOffset; + dword_ typeDescriptorOffset; + dword_ classDescriptorOffset; +#else + RTTICompleteObjectLocator(const std::type_info &info) : + signature(0), offset(0), cdOffset(0), + pTypeDescriptor(&info), + pClassDescriptor(new RTTIClassHierarchyDescriptor()) { + } + + ~RTTICompleteObjectLocator() { + delete pClassDescriptor; + } + + dword_ signature; + dword_ offset; + dword_ cdOffset; + const std::type_info *pTypeDescriptor; + struct RTTIClassHierarchyDescriptor *pClassDescriptor; +#endif + }; + + + struct VirtualTableBase { + + static VirtualTableBase &getVTable(void *instance) { + fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance); + return *vt; + } + + VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { } + + void *getCookie(int index) { + return _firstMethod[-2 - index]; + } + + void setCookie(int index, void *value) { + _firstMethod[-2 - index] = value; + } + + void *getMethod(unsigned int index) const { + return _firstMethod[index]; + } + + void setMethod(unsigned int index, void *method) { + _firstMethod[index] = method; + } + + protected: + void **_firstMethod; + }; + + template + struct VirtualTable : public VirtualTableBase { + + class Handle { + + friend struct VirtualTable; + + void **firstMethod; + + Handle(void **method) : firstMethod(method) { } + + public: + + VirtualTable &restore() { + VirtualTable *vt = (VirtualTable *) this; + return *vt; + } + }; + + static VirtualTable &getVTable(C &instance) { + fakeit::VirtualTable *vt = (fakeit::VirtualTable *) (&instance); + return *vt; + } + + void copyFrom(VirtualTable &from) { + unsigned int size = VTUtils::getVTSize(); + for (unsigned int i = 0; i < size; i++) { + _firstMethod[i] = from.getMethod(i); + } + if (VTUtils::hasVirtualDestructor()) + setCookie(dtorCookieIndex, from.getCookie(dtorCookieIndex)); + } + + VirtualTable() : VirtualTable(buildVTArray()) { + } + + ~VirtualTable() { + + } + + void dispose() { + _firstMethod--; + RTTICompleteObjectLocator *locator = (RTTICompleteObjectLocator *) _firstMethod[0]; + delete locator; + _firstMethod -= numOfCookies; + delete[] _firstMethod; + } + + + unsigned int dtor(int) { + C *c = (C *) this; + C &cRef = *c; + auto vt = VirtualTable::getVTable(cRef); + void *dtorPtr = vt.getCookie(dtorCookieIndex); + void(*method)(C *) = reinterpret_cast(dtorPtr); + method(c); + return 0; + } + + void setDtor(void *method) { + + + + + + void *dtorPtr = union_cast(&VirtualTable::dtor); + unsigned int index = VTUtils::getDestructorOffset(); + _firstMethod[index] = dtorPtr; + setCookie(dtorCookieIndex, method); + } + + unsigned int getSize() { + return VTUtils::getVTSize(); + } + + void initAll(void *value) { + auto size = getSize(); + for (unsigned int i = 0; i < size; i++) { + setMethod(i, value); + } + } + + Handle createHandle() { + Handle h(_firstMethod); + return h; + } + + private: + + class SimpleType { + }; + + static_assert(sizeof(unsigned int (SimpleType::*)()) == sizeof(unsigned int (C::*)()), + "Can't mock a type with multiple inheritance or with non-polymorphic base class"); + static const unsigned int numOfCookies = 3; + static const unsigned int dtorCookieIndex = numOfCookies - 1; + + static void **buildVTArray() { + int vtSize = VTUtils::getVTSize(); + auto array = new void *[vtSize + numOfCookies + 1]{}; + RTTICompleteObjectLocator *objectLocator = new RTTICompleteObjectLocator( + typeid(C)); + array += numOfCookies; + array[0] = objectLocator; + array++; + return array; + } + + VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) { + } + }; +} +#else +#ifndef __clang__ +#include +#include + +namespace fakeit { + template + class has_one_base { + }; + + template + class has_one_base> : public std::false_type { + }; + + template + class has_one_base> + : public has_one_base::type> { + }; + + template<> + class has_one_base> : public std::true_type { + }; + + template + class is_simple_inheritance_layout : public has_one_base::type> { + }; +} + +#endif + +namespace fakeit { + + struct VirtualTableBase { + + static VirtualTableBase &getVTable(void *instance) { + fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance); + return *vt; + } + + VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { } + + void *getCookie(int index) { + return _firstMethod[-3 - index]; + } + + void setCookie(int index, void *value) { + _firstMethod[-3 - index] = value; + } + + void *getMethod(unsigned int index) const { + return _firstMethod[index]; + } + + void setMethod(unsigned int index, void *method) { + _firstMethod[index] = method; + } + + protected: + void **_firstMethod; + }; + + template + struct VirtualTable : public VirtualTableBase { + +#ifndef __clang__ + static_assert(is_simple_inheritance_layout::value, "Can't mock a type with multiple inheritance"); +#endif + + class Handle { + + friend struct VirtualTable; + void **firstMethod; + + Handle(void **method) : + firstMethod(method) { + } + + public: + + VirtualTable &restore() { + VirtualTable *vt = (VirtualTable *) this; + return *vt; + } + }; + + static VirtualTable &getVTable(C &instance) { + fakeit::VirtualTable *vt = (fakeit::VirtualTable *) (&instance); + return *vt; + } + + void copyFrom(VirtualTable &from) { + unsigned int size = VTUtils::getVTSize(); + + for (size_t i = 0; i < size; ++i) { + _firstMethod[i] = from.getMethod(i); + } + } + + VirtualTable() : + VirtualTable(buildVTArray()) { + } + + void dispose() { + _firstMethod--; + _firstMethod--; + _firstMethod -= numOfCookies; + delete[] _firstMethod; + } + + unsigned int dtor(int) { + C *c = (C *) this; + C &cRef = *c; + auto vt = VirtualTable::getVTable(cRef); + unsigned int index = VTUtils::getDestructorOffset(); + void *dtorPtr = vt.getMethod(index); + void(*method)(C *) = union_cast(dtorPtr); + method(c); + return 0; + } + + + void setDtor(void *method) { + unsigned int index = VTUtils::getDestructorOffset(); + void *dtorPtr = union_cast(&VirtualTable::dtor); + + + _firstMethod[index] = method; + + _firstMethod[index + 1] = dtorPtr; + } + + + unsigned int getSize() { + return VTUtils::getVTSize(); + } + + void initAll(void *value) { + unsigned int size = getSize(); + for (unsigned int i = 0; i < size; i++) { + setMethod(i, value); + } + } + + const std::type_info *getTypeId() { + return (const std::type_info *) (_firstMethod[-1]); + } + + Handle createHandle() { + Handle h(_firstMethod); + return h; + } + + private: + static const unsigned int numOfCookies = 2; + + static void **buildVTArray() { + int size = VTUtils::getVTSize(); + auto array = new void *[size + 2 + numOfCookies]{}; + array += numOfCookies; + array++; + array[0] = const_cast(&typeid(C)); + array++; + return array; + } + + VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) { + } + + }; +} +#endif +namespace fakeit { + + template + struct MethodInvocationHandler : Destructible { + virtual R handleMethodInvocation(const typename fakeit::production_arg::type... args) = 0; + }; + +} +#include + + +namespace fakeit +{ + namespace details + { + template + class FakeObjectImpl + { + public: + void initializeDataMembersArea() + { + for (size_t i = 0; i < instanceAreaSize; ++i) + { + instanceArea[i] = (char) 0; + } + } + + protected: + VirtualTable vtable; + char instanceArea[instanceAreaSize]; + }; + + template + class FakeObjectImpl<0, C, BaseClasses...> + { + public: + void initializeDataMembersArea() + {} + + protected: + VirtualTable vtable; + }; + } + + template + class FakeObject + : public details::FakeObjectImpl), C, BaseClasses...> + { + FakeObject(FakeObject const&) = delete; + FakeObject& operator=(FakeObject const&) = delete; + + public: + FakeObject() + { + this->initializeDataMembersArea(); + } + + ~FakeObject() + { + this->vtable.dispose(); + } + + void setMethod(unsigned int index, void* method) + { + this->vtable.setMethod(index, method); + } + + VirtualTable& getVirtualTable() + { + return this->vtable; + } + + void setVirtualTable(VirtualTable& t) + { + this->vtable = t; + } + + void setDtor(void* dtor) + { + this->vtable.setDtor(dtor); + } + }; +} +#include + +namespace fakeit { + + class Finally { + private: + std::function _finallyClause; + + Finally(const Finally &) = delete; + + Finally &operator=(const Finally &) = delete; + + public: + explicit Finally(std::function f) : + _finallyClause(f) { + } + + Finally(Finally&& other) { + _finallyClause.swap(other._finallyClause); + } + + ~Finally() { + _finallyClause(); + } + }; +} +namespace fakeit { + + struct MethodProxy { + + MethodProxy(unsigned int id, unsigned int offset, void *vMethod) : + _id(id), + _offset(offset), + _vMethod(vMethod) { + } + + unsigned int getOffset() const { + return _offset; + } + + unsigned int getId() const { + return _id; + } + + void *getProxy() const { + return union_cast(_vMethod); + } + + private: + unsigned int _id; + unsigned int _offset; + void *_vMethod; + }; +} +#include + + +namespace fakeit { + + struct InvocationHandlerCollection { + static const unsigned int VtCookieIndex = 0; + + virtual Destructible *getInvocatoinHandlerPtrById(unsigned int index) = 0; + + static InvocationHandlerCollection *getInvocationHandlerCollection(void *instance) { + VirtualTableBase &vt = VirtualTableBase::getVTable(instance); + InvocationHandlerCollection *invocationHandlerCollection = (InvocationHandlerCollection *) vt.getCookie( + InvocationHandlerCollection::VtCookieIndex); + return invocationHandlerCollection; + } + + virtual ~InvocationHandlerCollection() { } + }; + + + template + class MethodProxyCreator { + + + + public: + + template + MethodProxy createMethodProxy(unsigned int offset) { + return MethodProxy(id, offset, union_cast(&MethodProxyCreator::methodProxyX < id > )); + } + + template + MethodProxy createMethodProxyStatic(unsigned int offset) { + return MethodProxy(id, offset, union_cast(&MethodProxyCreator::methodProxyXStatic < id > )); + } + + protected: + + R methodProxy(unsigned int id, const typename fakeit::production_arg::type... args) { + InvocationHandlerCollection *invocationHandlerCollection = InvocationHandlerCollection::getInvocationHandlerCollection( + this); + MethodInvocationHandler *invocationHandler = + (MethodInvocationHandler *) invocationHandlerCollection->getInvocatoinHandlerPtrById( + id); + return invocationHandler->handleMethodInvocation(std::forward::type>(args)...); + } + + template + R methodProxyX(arglist ... args) { + return methodProxy(id, std::forward::type>(args)...); + } + + static R methodProxyStatic(void* instance, unsigned int id, const typename fakeit::production_arg::type... args) { + InvocationHandlerCollection *invocationHandlerCollection = InvocationHandlerCollection::getInvocationHandlerCollection( + instance); + MethodInvocationHandler *invocationHandler = + (MethodInvocationHandler *) invocationHandlerCollection->getInvocatoinHandlerPtrById( + id); + return invocationHandler->handleMethodInvocation(std::forward::type>(args)...); + } + + template + static R methodProxyXStatic(void* instance, arglist ... args) { + return methodProxyStatic(instance, id, std::forward::type>(args)...); + } + }; +} + +namespace fakeit { + + class InvocationHandlers : public InvocationHandlerCollection { + std::vector> &_methodMocks; + std::vector &_offsets; + + unsigned int getOffset(unsigned int id) const + { + unsigned int offset = 0; + for (; offset < _offsets.size(); offset++) { + if (_offsets[offset] == id) { + break; + } + } + return offset; + } + + public: + InvocationHandlers( + std::vector> &methodMocks, + std::vector &offsets) : + _methodMocks(methodMocks), _offsets(offsets) { + for (std::vector::iterator it = _offsets.begin(); it != _offsets.end(); ++it) + { + *it = std::numeric_limits::max(); + } + } + + Destructible *getInvocatoinHandlerPtrById(unsigned int id) override { + unsigned int offset = getOffset(id); + std::shared_ptr ptr = _methodMocks[offset]; + return ptr.get(); + } + + }; + + template + struct DynamicProxy { + + static_assert(std::is_polymorphic::value, "DynamicProxy requires a polymorphic type"); + + DynamicProxy(C &inst) : + instance(inst), + originalVtHandle(VirtualTable::getVTable(instance).createHandle()), + _methodMocks(VTUtils::getVTSize()), + _offsets(VTUtils::getVTSize()), + _invocationHandlers(_methodMocks, _offsets) { + _cloneVt.copyFrom(originalVtHandle.restore()); + _cloneVt.setCookie(InvocationHandlerCollection::VtCookieIndex, &_invocationHandlers); + getFake().setVirtualTable(_cloneVt); + } + + void detach() { + getFake().setVirtualTable(originalVtHandle.restore()); + } + + ~DynamicProxy() { + _cloneVt.dispose(); + } + + C &get() { + return instance; + } + + void Reset() { + _methodMocks = {}; + _methodMocks.resize(VTUtils::getVTSize()); + _members = {}; + _offsets = {}; + _offsets.resize(VTUtils::getVTSize()); + _cloneVt.copyFrom(originalVtHandle.restore()); + } + + void Clear() + { + } + + template + void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler *methodInvocationHandler) { + auto offset = VTUtils::getOffset(vMethod); + MethodProxyCreator creator; + bind(creator.template createMethodProxy(offset), methodInvocationHandler); + } + + void stubDtor(MethodInvocationHandler *methodInvocationHandler) { + auto offset = VTUtils::getDestructorOffset(); + MethodProxyCreator creator; + + + + + + +#ifdef _MSC_VER + bindDtor(creator.createMethodProxyStatic<0>(offset), methodInvocationHandler); +#else + bindDtor(creator.createMethodProxy<0>(offset), methodInvocationHandler); +#endif + } + + template + bool isMethodStubbed(R(C::*vMethod)(arglist...)) { + unsigned int offset = VTUtils::getOffset(vMethod); + return isBinded(offset); + } + + bool isDtorStubbed() { + unsigned int offset = VTUtils::getDestructorOffset(); + return isBinded(offset); + } + + template + Destructible *getMethodMock(R(C::*vMethod)(arglist...)) { + auto offset = VTUtils::getOffset(vMethod); + std::shared_ptr ptr = _methodMocks[offset]; + return ptr.get(); + } + + Destructible *getDtorMock() { + auto offset = VTUtils::getDestructorOffset(); + std::shared_ptr ptr = _methodMocks[offset]; + return ptr.get(); + } + + template + void stubDataMember(DataType C::*member, const arglist &... initargs) { + DataType C::*theMember = (DataType C::*) member; + C &mock = get(); + DataType *memberPtr = &(mock.*theMember); + _members.push_back( + std::shared_ptr > + {new DataMemeberWrapper < DataType, arglist...>(memberPtr, + initargs...)}); + } + + template + void getMethodMocks(std::vector &into) const { + for (std::shared_ptr ptr : _methodMocks) { + DataType p = dynamic_cast(ptr.get()); + if (p) { + into.push_back(p); + } + } + } + + VirtualTable &getOriginalVT() { + VirtualTable &vt = originalVtHandle.restore(); + return vt; + } + + template + Finally createRaiiMethodSwapper(R(C::*vMethod)(arglist...)) { + auto offset = VTUtils::getOffset(vMethod); + auto fakeMethod = getFake().getVirtualTable().getMethod(offset); + auto originalMethod = getOriginalVT().getMethod(offset); + + getFake().setMethod(offset, originalMethod); + return Finally{[&, offset, fakeMethod](){ + getFake().setMethod(offset, fakeMethod); + }}; + } + + private: + + template + class DataMemeberWrapper : public Destructible { + private: + DataType *dataMember; + public: + DataMemeberWrapper(DataType *dataMem, const arglist &... initargs) : + dataMember(dataMem) { + new(dataMember) DataType{initargs ...}; + } + + ~DataMemeberWrapper() override + { + dataMember->~DataType(); + } + }; + + static_assert(sizeof(C) == sizeof(FakeObject), "This is a problem"); + + C &instance; + typename VirtualTable::Handle originalVtHandle; + VirtualTable _cloneVt; + + std::vector> _methodMocks; + std::vector> _members; + std::vector _offsets; + InvocationHandlers _invocationHandlers; + + FakeObject &getFake() { + return reinterpret_cast &>(instance); + } + + void bind(const MethodProxy &methodProxy, Destructible *invocationHandler) { + getFake().setMethod(methodProxy.getOffset(), methodProxy.getProxy()); + _methodMocks[methodProxy.getOffset()].reset(invocationHandler); + _offsets[methodProxy.getOffset()] = methodProxy.getId(); + } + + void bindDtor(const MethodProxy &methodProxy, Destructible *invocationHandler) { + getFake().setDtor(methodProxy.getProxy()); + _methodMocks[methodProxy.getOffset()].reset(invocationHandler); + _offsets[methodProxy.getOffset()] = methodProxy.getId(); + } + + template + DataType getMethodMock(unsigned int offset) { + std::shared_ptr ptr = _methodMocks[offset]; + return dynamic_cast(ptr.get()); + } + + template + void checkMultipleInheritance() { + C *ptr = (C *) (unsigned int) 1; + BaseClass *basePtr = ptr; + int delta = (unsigned long) basePtr - (unsigned long) ptr; + if (delta > 0) { + FAIL("multiple inheritance is not supported"); + } + } + + bool isBinded(unsigned int offset) { + std::shared_ptr ptr = _methodMocks[offset]; + return ptr.get() != nullptr; + } + + }; +} +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fakeit { + + template + struct apply_func { + template + static R applyTuple(FunctionType&& f, std::tuple &t, Args &... args) { + return apply_func::template applyTuple(std::forward(f), t, std::get(t), args...); + } + }; + + template<> + struct apply_func < 0 > { + template + static R applyTuple(FunctionType&& f, std::tuple & , Args &... args) { + return std::forward(f)(args...); + } + }; + + struct TupleDispatcher { + + template + static R applyTuple(FunctionType&& f, std::tuple &t) { + return apply_func::template applyTuple(std::forward(f), t); + } + + template + static R invoke(FunctionType&& func, const std::tuple &arguments) { + std::tuple &args = const_cast &>(arguments); + return applyTuple(std::forward(func), args); + } + + template + static void for_each(TupleType &&, FunctionType &, + std::integral_constant::type>::value>) { + } + + template::type>::value>::type> + static void for_each(TupleType &&t, FunctionType &f, std::integral_constant) { + f(I, std::get < I >(t)); + for_each(std::forward < TupleType >(t), f, std::integral_constant()); + } + + template + static void for_each(TupleType &&t, FunctionType &f) { + for_each(std::forward < TupleType >(t), f, std::integral_constant()); + } + + template + static void for_each(TupleType1 &&, TupleType2 &&, FunctionType &, + std::integral_constant::type>::value>) { + } + + template::type>::value>::type> + static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f, std::integral_constant) { + f(I, std::get < I >(t), std::get < I >(t2)); + for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant()); + } + + template + static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f) { + for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant()); + } + }; +} +namespace fakeit { + + template + struct ActualInvocationHandler : Destructible { + virtual R handleMethodInvocation(ArgumentsTuple & args) = 0; + }; + +} +#include +#include +#include +#include +#include +#include + +namespace fakeit { + + struct DefaultValueInstatiationException { + virtual ~DefaultValueInstatiationException() = default; + + virtual std::string what() const = 0; + }; + + + template + struct is_constructible_type { + static const bool value = + std::is_default_constructible::type>::value + && !std::is_abstract::type>::value; + }; + + template + struct DefaultValue; + + template + struct DefaultValue::value>::type> { + static C &value() { + if (std::is_reference::value) { + typename naked_type::type *ptr = nullptr; + return *ptr; + } + + FAIL((std::string("Type ") + std::string(typeid(C).name()) + + std::string( + " is not default constructible. Could not instantiate a default return value"))); + } + }; + + template + struct DefaultValue::value>::type> { + static C &value() { + static typename naked_type::type val{}; + return val; + } + }; + + + template<> + struct DefaultValue { + static void value() { + return; + } + }; + + template<> + struct DefaultValue { + static bool &value() { + static bool value{false}; + return value; + } + }; + + template<> + struct DefaultValue { + static char &value() { + static char value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static char16_t &value() { + static char16_t value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static char32_t &value() { + static char32_t value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static wchar_t &value() { + static wchar_t value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static short &value() { + static short value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static int &value() { + static int value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static long &value() { + static long value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static long long &value() { + static long long value{0}; + return value; + } + }; + + template<> + struct DefaultValue { + static std::string &value() { + static std::string value{}; + return value; + } + }; + +} +#include +#include + + +namespace fakeit { + + struct IMatcher : Destructible { + ~IMatcher() = default; + virtual std::string format() const = 0; + }; + + template + struct TypedMatcher : IMatcher { + virtual bool matches(const ActualT &actual) const = 0; + }; + + template + struct ComparisonMatcherCreatorBase { + using ExpectedT = typename naked_type::type; + + ExpectedTRef _expectedRef; + + template + ComparisonMatcherCreatorBase(T &&expectedRef) + : _expectedRef(std::forward(expectedRef)) { + } + + template + struct MatcherBase : public TypedMatcher { + const ExpectedT _expected; + + MatcherBase(ExpectedTRef expected) + : _expected{std::forward(expected)} { + } + }; + + template + struct MatcherBase::value && std::is_array::value>::type> : public TypedMatcher { + ExpectedT _expected; + + MatcherBase(ExpectedTRef expected) { + std::memcpy(_expected, expected, sizeof(_expected)); + } + }; + }; + + namespace internal { + struct AnyMatcherCreator{ + template + struct IsTypeCompatible : std::true_type {}; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public TypedMatcher { + bool matches(const ActualT &) const override { + return true; + } + + std::string format() const override { + return "Any"; + } + }; + + return new Matcher(); + } + }; + + template + struct EqMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible() == std::declval())>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return actual == this->_expected; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct GtMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible() > std::declval())>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string(">") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return actual > this->_expected; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct GeMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible() >= std::declval())>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string(">=") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return actual >= this->_expected; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct LtMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible() < std::declval())>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string("<") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return actual < this->_expected; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct LeMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible() <= std::declval())>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string("<=") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return actual <= this->_expected; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct NeMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible() != std::declval())>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string("!=") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return actual != this->_expected; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct StrEqMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible(), std::declval()))>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return std::strcmp(actual, this->_expected.c_str()) == 0; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct StrGtMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible(), std::declval()))>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string(">") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return std::strcmp(actual, this->_expected.c_str()) > 0; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct StrGeMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible(), std::declval()))>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string(">=") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return std::strcmp(actual, this->_expected.c_str()) >= 0; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct StrLtMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible(), std::declval()))>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string("<") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return std::strcmp(actual, this->_expected.c_str()) < 0; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct StrLeMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible(), std::declval()))>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string("<=") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return std::strcmp(actual, this->_expected.c_str()) <= 0; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct StrNeMatcherCreator : public ComparisonMatcherCreatorBase { + using ExpectedT = typename ComparisonMatcherCreatorBase::ExpectedT; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible(), std::declval()))>> : std::true_type {}; + + using ComparisonMatcherCreatorBase::ComparisonMatcherCreatorBase; + + template + TypedMatcher *createMatcher() const { + struct Matcher : public ComparisonMatcherCreatorBase::template MatcherBase { + using ComparisonMatcherCreatorBase::template MatcherBase::MatcherBase; + + virtual std::string format() const override { + return std::string("!=") + TypeFormatter::format(this->_expected); + } + + virtual bool matches(const ActualT &actual) const override { + return std::strcmp(actual, this->_expected.c_str()) != 0; + } + }; + + return new Matcher(std::forward(this->_expectedRef)); + } + }; + + template + struct ApproxEqCreator { + using ExpectedT = typename naked_type::type; + using ExpectedMarginT = typename naked_type::type; + + template + struct IsTypeCompatible : std::false_type {}; + + template + struct IsTypeCompatible() - std::declval()) <= std::declval())>> : std::true_type {}; + + ExpectedTRef _expectedRef; + ExpectedMarginTRef _expectedMarginRef; + + template + ApproxEqCreator(T &&expectedRef, U &&expectedMarginRef) + : _expectedRef(std::forward(expectedRef)) + , _expectedMarginRef(std::forward(expectedMarginRef)) { + } + + template + TypedMatcher *createMatcher() const { + struct Matcher : public TypedMatcher { + const ExpectedT _expected; + const ExpectedMarginT _expectedMargin; + + Matcher(ExpectedTRef expected, ExpectedMarginTRef expectedMargin) + : _expected{std::forward(expected)} + , _expectedMargin{std::forward(expectedMargin)} { + } + + virtual std::string format() const override { + return TypeFormatter::format(this->_expected) + std::string("+/-") + TypeFormatter::format(this->_expectedMargin); + } + + virtual bool matches(const ActualT &actual) const override { + return std::abs(actual - this->_expected) <= this->_expectedMargin; + } + }; + + return new Matcher(std::forward(this->_expectedRef), std::forward(this->_expectedMarginRef)); + } + }; + } + +/* clang-format off */ + struct AnyMatcher { + } static _; +/* clang-format on */ + + template + internal::AnyMatcherCreator Any() { + static_assert(sizeof(T) >= 0, "To maintain backward compatibility, this function takes an useless template argument."); + internal::AnyMatcherCreator mc; + return mc; + } + + inline internal::AnyMatcherCreator Any() { + internal::AnyMatcherCreator mc; + return mc; + } + + template + internal::EqMatcherCreator Eq(T &&arg) { + internal::EqMatcherCreator mc(std::forward(arg)); + return mc; + } + + template + internal::GtMatcherCreator Gt(T &&arg) { + internal::GtMatcherCreator mc(std::forward(arg)); + return mc; + } + + template + internal::GeMatcherCreator Ge(T &&arg) { + internal::GeMatcherCreator mc(std::forward(arg)); + return mc; + } + + template + internal::LtMatcherCreator Lt(T &&arg) { + internal::LtMatcherCreator mc(std::forward(arg)); + return mc; + } + + template + internal::LeMatcherCreator Le(T &&arg) { + internal::LeMatcherCreator mc(std::forward(arg)); + return mc; + } + + template + internal::NeMatcherCreator Ne(T &&arg) { + internal::NeMatcherCreator mc(std::forward(arg)); + return mc; + } + + inline internal::StrEqMatcherCreator StrEq(std::string&& arg) { + internal::StrEqMatcherCreator mc(std::move(arg)); + return mc; + } + + inline internal::StrEqMatcherCreator StrEq(const std::string& arg) { + internal::StrEqMatcherCreator mc(arg); + return mc; + } + + inline internal::StrGtMatcherCreator StrGt(std::string&& arg) { + internal::StrGtMatcherCreator mc(std::move(arg)); + return mc; + } + + inline internal::StrGtMatcherCreator StrGt(const std::string& arg) { + internal::StrGtMatcherCreator mc(arg); + return mc; + } + + inline internal::StrGeMatcherCreator StrGe(std::string&& arg) { + internal::StrGeMatcherCreator mc(std::move(arg)); + return mc; + } + + inline internal::StrGeMatcherCreator StrGe(const std::string& arg) { + internal::StrGeMatcherCreator mc(arg); + return mc; + } + + inline internal::StrLtMatcherCreator StrLt(std::string&& arg) { + internal::StrLtMatcherCreator mc(std::move(arg)); + return mc; + } + + inline internal::StrLtMatcherCreator StrLt(const std::string& arg) { + internal::StrLtMatcherCreator mc(arg); + return mc; + } + + inline internal::StrLeMatcherCreator StrLe(std::string&& arg) { + internal::StrLeMatcherCreator mc(std::move(arg)); + return mc; + } + + inline internal::StrLeMatcherCreator StrLe(const std::string& arg) { + internal::StrLeMatcherCreator mc(arg); + return mc; + } + + inline internal::StrNeMatcherCreator StrNe(std::string&& arg) { + internal::StrNeMatcherCreator mc(std::move(arg)); + return mc; + } + + inline internal::StrNeMatcherCreator StrNe(const std::string& arg) { + internal::StrNeMatcherCreator mc(arg); + return mc; + } + + template::type>::value, int>::type = 0, + typename std::enable_if::type>::value, int>::type = 0> + internal::ApproxEqCreator ApproxEq(T &&expected, U &&margin) { + internal::ApproxEqCreator mc(std::forward(expected), std::forward(margin)); + return mc; + } + +} + +namespace fakeit { + + template + struct ArgumentsMatcherInvocationMatcher : public ActualInvocation::Matcher { + + virtual ~ArgumentsMatcherInvocationMatcher() { + for (unsigned int i = 0; i < _matchers.size(); i++) + delete _matchers[i]; + } + + ArgumentsMatcherInvocationMatcher(const std::vector &args) + : _matchers(args) { + } + + virtual bool matches(ActualInvocation &invocation) override { + if (invocation.getActualMatcher() == this) + return true; + return matches(invocation.getActualArguments()); + } + + virtual std::string format() const override { + std::ostringstream out; + out << "("; + for (unsigned int i = 0; i < _matchers.size(); i++) { + if (i > 0) out << ", "; + IMatcher *m = dynamic_cast(_matchers[i]); + out << m->format(); + } + out << ")"; + return out.str(); + } + + private: + + struct MatchingLambda { + MatchingLambda(const std::vector &matchers) + : _matchers(matchers) { + } + + template + void operator()(int index, A &actualArg) { + TypedMatcher::type> *matcher = + dynamic_cast::type> *>(_matchers[index]); + if (_matching) + _matching = matcher->matches(actualArg); + } + + bool isMatching() { + return _matching; + } + + private: + bool _matching = true; + const std::vector &_matchers; + }; + + virtual bool matches(ArgumentsTuple& actualArguments) { + MatchingLambda l(_matchers); + fakeit::TupleDispatcher::for_each(actualArguments, l); + return l.isMatching(); + } + + const std::vector _matchers; + }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + template + struct UserDefinedInvocationMatcher : ActualInvocation::Matcher { + virtual ~UserDefinedInvocationMatcher() = default; + + UserDefinedInvocationMatcher(const std::function& match) + : matcher{match} { + } + + virtual bool matches(ActualInvocation &invocation) override { + if (invocation.getActualMatcher() == this) + return true; + return matches(invocation.getActualArguments()); + } + + virtual std::string format() const override { + return {"( user defined matcher )"}; + } + + private: + virtual bool matches(ArgumentsTuple& actualArguments) { + return TupleDispatcher::invoke::type...>(matcher, actualArguments); + } + + const std::function matcher; + }; + + template + struct DefaultInvocationMatcher : public ActualInvocation::Matcher { + + virtual ~DefaultInvocationMatcher() = default; + + DefaultInvocationMatcher() { + } + + virtual bool matches(ActualInvocation &invocation) override { + return matches(invocation.getActualArguments()); + } + + virtual std::string format() const override { + return {"( Any arguments )"}; + } + + private: + + virtual bool matches(const ArgumentsTuple&) { + return true; + } + }; + +} + +namespace fakeit { + + + template + class RecordedMethodBody : public MethodInvocationHandler, public ActualInvocationsSource, public ActualInvocationsContainer { + + struct MatchedInvocationHandler : ActualInvocationHandler { + + virtual ~MatchedInvocationHandler() = default; + + MatchedInvocationHandler(typename ActualInvocation::Matcher *matcher, + ActualInvocationHandler *invocationHandler) : + _matcher{matcher}, _invocationHandler{invocationHandler} { + } + + virtual R handleMethodInvocation(ArgumentsTuple & args) override + { + Destructible &destructable = *_invocationHandler; + ActualInvocationHandler &invocationHandler = dynamic_cast &>(destructable); + return invocationHandler.handleMethodInvocation(args); + } + + typename ActualInvocation::Matcher &getMatcher() const { + Destructible &destructable = *_matcher; + typename ActualInvocation::Matcher &matcher = dynamic_cast::Matcher &>(destructable); + return matcher; + } + + private: + std::shared_ptr _matcher; + std::shared_ptr _invocationHandler; + }; + + + FakeitContext &_fakeit; + MethodInfo _method; + + std::vector> _invocationHandlers; + std::vector> _actualInvocations; + + MatchedInvocationHandler *buildMatchedInvocationHandler( + typename ActualInvocation::Matcher *invocationMatcher, + ActualInvocationHandler *invocationHandler) { + return new MatchedInvocationHandler(invocationMatcher, invocationHandler); + } + + MatchedInvocationHandler *getInvocationHandlerForActualArgs(ActualInvocation &invocation) { + for (auto i = _invocationHandlers.rbegin(); i != _invocationHandlers.rend(); ++i) { + std::shared_ptr curr = *i; + Destructible &destructable = *curr; + MatchedInvocationHandler &im = asMatchedInvocationHandler(destructable); + if (im.getMatcher().matches(invocation)) { + return &im; + } + } + return nullptr; + } + + MatchedInvocationHandler &asMatchedInvocationHandler(Destructible &destructable) { + MatchedInvocationHandler &im = dynamic_cast(destructable); + return im; + } + + ActualInvocation &asActualInvocation(Destructible &destructable) const { + ActualInvocation &invocation = dynamic_cast &>(destructable); + return invocation; + } + + public: + + RecordedMethodBody(FakeitContext &fakeit, std::string name) : + _fakeit(fakeit), _method{MethodInfo::nextMethodOrdinal(), name} { } + + virtual ~RecordedMethodBody() FAKEIT_NO_THROWS { + } + + MethodInfo &getMethod() { + return _method; + } + + bool isOfMethod(MethodInfo &method) { + + return method.id() == _method.id(); + } + + void addMethodInvocationHandler(typename ActualInvocation::Matcher *matcher, + ActualInvocationHandler *invocationHandler) { + ActualInvocationHandler *mock = buildMatchedInvocationHandler(matcher, invocationHandler); + std::shared_ptr destructable{mock}; + _invocationHandlers.push_back(destructable); + } + + void reset() { + _invocationHandlers.clear(); + _actualInvocations.clear(); + } + + void clear() override { + _actualInvocations.clear(); + } + + R handleMethodInvocation(const typename fakeit::production_arg::type... args) override { + unsigned int ordinal = Invocation::nextInvocationOrdinal(); + MethodInfo &method = this->getMethod(); + auto actualInvocation = new ActualInvocation(ordinal, method, std::forward::type>(args)...); + + + std::shared_ptr actualInvocationDtor{actualInvocation}; + + auto invocationHandler = getInvocationHandlerForActualArgs(*actualInvocation); + if (invocationHandler) { + auto &matcher = invocationHandler->getMatcher(); + actualInvocation->setActualMatcher(&matcher); + _actualInvocations.push_back(actualInvocationDtor); + return invocationHandler->handleMethodInvocation(actualInvocation->getActualArguments()); + } + + UnexpectedMethodCallEvent event(UnexpectedType::Unmatched, *actualInvocation); + _fakeit.handle(event); + std::string format{_fakeit.format(event)}; + FAIL(format); + return R(); + } + + void scanActualInvocations(const std::function &)> &scanner) { + for (auto destructablePtr : _actualInvocations) { + ActualInvocation &invocation = asActualInvocation(*destructablePtr); + scanner(invocation); + } + } + + void getActualInvocations(std::unordered_set &into) const override { + for (auto destructablePtr : _actualInvocations) { + Invocation &invocation = asActualInvocation(*destructablePtr); + into.insert(&invocation); + } + } + + void setMethodDetails(const std::string &mockName, const std::string &methodName) { + const std::string fullName{mockName + "." + methodName}; + _method.setName(fullName); + } + + }; + +} +#include +#include +#include +#include +#include +#include + +namespace fakeit { + + struct Quantity { + Quantity(const int q) : + quantity(q) { + } + + const int quantity; + } static Once(1); + + template + struct Quantifier : public Quantity { + Quantifier(const int q, const R &val) : + Quantity(q), value(val) { + } + + const R &value; + }; + + template<> + struct Quantifier : public Quantity { + explicit Quantifier(const int q) : + Quantity(q) { + } + }; + + struct QuantifierFunctor : public Quantifier { + QuantifierFunctor(const int q) : + Quantifier(q) { + } + + template + Quantifier operator()(const R &value) { + return Quantifier(quantity, value); + } + }; + + template + struct Times : public Quantity { + + Times() : Quantity(q) { } + + template + static Quantifier of(const R &value) { + return Quantifier(q, value); + } + + static Quantifier Void() { + return Quantifier(q); + } + }; + +#if defined (__GNUG__) || (_MSC_VER >= 1900) + + inline QuantifierFunctor operator + "" + + _Times(unsigned long long n) { + return QuantifierFunctor((int) n); + } + + inline QuantifierFunctor operator + "" + + _Time(unsigned long long n) { + if (n != 1) + FAIL("Only 1_Time is supported. Use X_Times (with s) if X is bigger than 1"); + return QuantifierFunctor((int) n); + } + +#endif + +} +#include +#include +#include +#include + + +namespace fakeit { + + template + struct Action : Destructible { + virtual R invoke(const ArgumentsTuple &) = 0; + + virtual bool isDone() = 0; + }; + + template + struct Repeat : Action { + virtual ~Repeat() = default; + + Repeat(std::function::type...)> func) : + f(func), times(1) { + } + + Repeat(std::function::type...)> func, long t) : + f(func), times(t) { + } + + virtual R invoke(const ArgumentsTuple & args) override { + times--; + return TupleDispatcher::invoke(f, args); + } + + virtual bool isDone() override { + return times == 0; + } + + private: + std::function::type...)> f; + long times; + }; + + template + struct RepeatForever : public Action { + + virtual ~RepeatForever() = default; + + RepeatForever(std::function::type...)> func) : + f(func) { + } + + virtual R invoke(const ArgumentsTuple & args) override { + return TupleDispatcher::invoke(f, args); + } + + virtual bool isDone() override { + return false; + } + + private: + std::function::type...)> f; + }; + + template + struct ReturnDefaultValue : public Action { + virtual ~ReturnDefaultValue() = default; + + virtual R invoke(const ArgumentsTuple &) override { + return DefaultValue::value(); + } + + virtual bool isDone() override { + return false; + } + }; + + template + struct ReturnDelegateValue : public Action { + + ReturnDelegateValue(std::function::type...)> delegate) : _delegate(delegate) { } + + virtual ~ReturnDelegateValue() = default; + + virtual R invoke(const ArgumentsTuple & args) override { + return TupleDispatcher::invoke(_delegate, args); + } + + virtual bool isDone() override { + return false; + } + + private: + std::function::type...)> _delegate; + }; + +} + +namespace fakeit { + + namespace helper + { + template + struct ArgValue; + + template + struct ArgValidator; + + template + static void + Assign(std::tuple...> arg_vals, current_arg &&p, arglist &&... args); + + template + struct ParamWalker; + + } + + + template + struct MethodStubbingProgress { + + virtual ~MethodStubbingProgress() FAKEIT_THROWS { + } + + template + typename std::enable_if::value, MethodStubbingProgress &>::type + Return(const R &r) { + return Do([r](const typename fakeit::test_arg::type...) -> R { return r; }); + } + + template + typename std::enable_if::value, MethodStubbingProgress &>::type + Return(const R &r) { + return Do([&r](const typename fakeit::test_arg::type...) -> R { return r; }); + } + + template + typename std::enable_if::value, MethodStubbingProgress&>::type + Return(R&& r) { + auto store = std::make_shared(std::move(r)); + return Do([store](const typename fakeit::test_arg::type...) mutable -> R { + return std::move(*store); + }); + } + + MethodStubbingProgress & + Return(const Quantifier &q) { + const R &value = q.value; + auto method = [value](const arglist &...) -> R { return value; }; + return DoImpl(new Repeat(method, q.quantity)); + } + + template + MethodStubbingProgress & + Return(const first &f, const second &s, const tail &... t) { + Return(f); + return Return(s, t...); + } + + + template + typename std::enable_if::value, void>::type + AlwaysReturn(const R &r) { + return AlwaysDo([r](const typename fakeit::test_arg::type...) -> R { return r; }); + } + + template + typename std::enable_if::value, void>::type + AlwaysReturn(const R &r) { + return AlwaysDo([&r](const typename fakeit::test_arg::type...) -> R { return r; }); + } + + MethodStubbingProgress & + Return() { + return Do([](const typename fakeit::test_arg::type...) -> R { return DefaultValue::value(); }); + } + + void AlwaysReturn() { + return AlwaysDo([](const typename fakeit::test_arg::type...) -> R { return DefaultValue::value(); }); + } + + template + MethodStubbingProgress & + ReturnAndSet(R &&r, valuelist &&... arg_vals) { + return Do(GetAssigner(std::forward(r), + std::forward(arg_vals)...)); + } + + template + void AlwaysReturnAndSet(R &&r, valuelist &&... arg_vals) { + AlwaysDo(GetAssigner(std::forward(r), + std::forward(arg_vals)...)); + } + + virtual MethodStubbingProgress & + Do(std::function::type...)> method) { + return DoImpl(new Repeat(method)); + } + + template + MethodStubbingProgress & + Do(const Quantifier &q) { + return DoImpl(new Repeat(q.value, q.quantity)); + } + + template + MethodStubbingProgress & + Do(const first &f, const second &s, const tail &... t) { + Do(f); + return Do(s, t...); + } + + virtual void AlwaysDo(std::function::type...)> method) { + DoImpl(new RepeatForever(method)); + } + + protected: + + virtual MethodStubbingProgress &DoImpl(Action *action) = 0; + + private: + MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; + + template +#if FAKEIT_CPLUSPLUS >= 201402L + auto +#else + std::function::type...)> +#endif + GetAssigner(R &&r, valuelist &&... arg_vals) { + class Lambda { + public: + Lambda(R &&r, valuelist &&... arg_vals) + : vals_tuple{std::forward(r), std::forward(arg_vals)...} {} + + R operator()(typename fakeit::test_arg::type... args) { + helper::ParamWalker::Assign(vals_tuple, + std::forward(args)...); + return std::get<0>(vals_tuple); + } + + private: + ArgumentsTuple vals_tuple; + }; + + return Lambda(std::forward(r), std::forward(arg_vals)...); + } + + template +#if FAKEIT_CPLUSPLUS >= 201402L + auto +#else + std::function::type...)> +#endif + GetAssigner(R &&r, helper::ArgValue... arg_vals) { + class Lambda { + public: + Lambda(R &&r, helper::ArgValue... arg_vals) + : ret{std::forward(r)} + , vals_tuple{std::forward>(arg_vals)...} {} + + R operator()(typename fakeit::test_arg::type... args) { + helper::ArgValidator::CheckPositions(vals_tuple); + helper::Assign<1>(vals_tuple, std::forward(args)...); + return std::get<0>(ret); + } + + private: + std::tuple ret; + ArgumentsTuple...> vals_tuple; + }; + + return Lambda(std::forward(r), std::forward>(arg_vals)...); + } + + }; + + + template + struct MethodStubbingProgress { + + virtual ~MethodStubbingProgress() FAKEIT_THROWS { + } + + MethodStubbingProgress &Return() { + auto lambda = [](const typename fakeit::test_arg::type...) -> void { + return DefaultValue::value(); + }; + return Do(lambda); + } + + virtual MethodStubbingProgress &Do( + std::function::type...)> method) { + return DoImpl(new Repeat(method)); + } + + + void AlwaysReturn() { + return AlwaysDo([](const typename fakeit::test_arg::type...) -> void { return DefaultValue::value(); }); + } + + MethodStubbingProgress & + Return(const Quantifier &q) { + auto method = [](const arglist &...) -> void { return DefaultValue::value(); }; + return DoImpl(new Repeat(method, q.quantity)); + } + + template + MethodStubbingProgress & + ReturnAndSet(valuelist &&... arg_vals) { + return Do(GetAssigner(std::forward(arg_vals)...)); + } + + template + void AlwaysReturnAndSet(valuelist &&... arg_vals) { + AlwaysDo(GetAssigner(std::forward(arg_vals)...)); + } + + template + MethodStubbingProgress & + Do(const Quantifier &q) { + return DoImpl(new Repeat(q.value, q.quantity)); + } + + template + MethodStubbingProgress & + Do(const first &f, const second &s, const tail &... t) { + Do(f); + return Do(s, t...); + } + + virtual void AlwaysDo(std::function::type...)> method) { + DoImpl(new RepeatForever(method)); + } + + protected: + + virtual MethodStubbingProgress &DoImpl(Action *action) = 0; + + private: + MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; + + template +#if FAKEIT_CPLUSPLUS >= 201402L + auto +#else + std::function::type...)> +#endif + GetAssigner(valuelist &&... arg_vals) { + class Lambda { + public: + Lambda(valuelist &&... arg_vals) + : vals_tuple{std::forward(arg_vals)...} {} + + void operator()(typename fakeit::test_arg::type... args) { + helper::ParamWalker::Assign(vals_tuple, + std::forward(args)...); + } + + private: + ArgumentsTuple vals_tuple; + }; + + return Lambda(std::forward(arg_vals)...); + } + + template +#if FAKEIT_CPLUSPLUS >= 201402L + auto +#else + std::function::type...)> +#endif + GetAssigner(helper::ArgValue... arg_vals) { + class Lambda { + public: + Lambda(helper::ArgValue... arg_vals) + : vals_tuple{std::forward>(arg_vals)...} {} + + void operator()(typename fakeit::test_arg::type... args) { + helper::ArgValidator::CheckPositions(vals_tuple); + helper::Assign<1>(vals_tuple, std::forward(args)...); + } + + private: + ArgumentsTuple...> vals_tuple; + }; + + return Lambda(std::forward>(arg_vals)...); + } + + }; + + + namespace helper + { + template + struct ArgValue + { + ArgValue(T &&v): value ( std::forward(v) ) {} + constexpr static int pos = N; + T value; + }; + + template + struct ArgValidator + { + template + static void CheckPositions(const std::tuple...> arg_vals) + { +#if FAKEIT_CPLUSPLUS >= 201402L && !defined(_WIN32) + static_assert(std::get(arg_vals).pos <= max_index, + "Argument index out of range"); + ArgValidator::CheckPositions(arg_vals); +#else + (void)arg_vals; +#endif + } + }; + + template + struct ArgValidator + { + template + static void CheckPositions(T) {} + }; + + template + typename std::enable_if::value, + typename std::remove_pointer::type &>::type + GetArg(current_arg &&t) + { + return *t; + } + + template + typename std::enable_if::value, current_arg>::type + GetArg(current_arg &&t) + { + return std::forward(t); + } + + template + struct ParamWalker { + template + static void + Assign(ArgumentsTuple arg_vals, current_arg &&p, arglist&&... args) { + ParamWalker::template Assign(arg_vals, std::forward(args)...); + GetArg(std::forward(p)) = std::get(arg_vals); + } + }; + + template<> + struct ParamWalker<0> { + template + static void Assign(ArgumentsTuple, arglist... ) {} + }; + + template + struct ArgLocator { + template + static void AssignArg(current_arg &&p, std::tuple...> arg_vals) { +#if FAKEIT_CPLUSPLUS >= 201703L && !defined (_WIN32) + if constexpr (std::get(arg_vals).pos == arg_index) + GetArg(std::forward(p)) = std::get(arg_vals).value; +#else + if (std::get(arg_vals).pos == arg_index) + Set(std::forward(p), std::get(arg_vals).value); +#endif + else if (check_index > 0) + ArgLocator::AssignArg(std::forward(p), arg_vals); + } + +#if FAKEIT_CPLUSPLUS < 201703L || defined (_WIN32) + private: + template + static + typename std::enable_if())), U>::value, void>::type + Set(T &&p, U &&v) + { + GetArg(std::forward(p)) = v; + } + + template + static + typename std::enable_if())), U>::value, void>::type + Set(T &&, U &&) + { + throw std::logic_error("ReturnAndSet(): Invalid value type"); + } +#endif + + }; + + template + struct ArgLocator { + template + static void AssignArg(current_arg, T) { + } + }; + + template + static void + Assign(std::tuple...> arg_vals, current_arg &&p, arglist &&... args) { + ArgLocator::AssignArg(std::forward(p), arg_vals); + Assign(arg_vals, std::forward(args)...); + } + + template + static void Assign(std::tuple) {} + + } + + + namespace placeholders + { + using namespace std::placeholders; + + template (std::is_placeholder::value), bool>::type = true> + helper::ArgValue::value> + operator<=(PlaceHolder, ArgType &&arg) + { + return { std::forward(arg) }; + } + + } + + using placeholders::operator <=; +} +#include + + + +namespace fakeit { + + + template + struct ActionSequence : ActualInvocationHandler { + + ActionSequence() { + clear(); + } + + void AppendDo(Action *action) { + append(action); + } + + virtual R handleMethodInvocation(ArgumentsTuple & args) override + { + std::shared_ptr destructablePtr = _recordedActions.front(); + Destructible &destructable = *destructablePtr; + Action &action = dynamic_cast &>(destructable); + std::function finallyClause = [&]() -> void { + if (action.isDone()) + { + _recordedActions.erase(_recordedActions.begin()); + _usedActions.push_back(destructablePtr); + } + }; + Finally onExit(finallyClause); + return action.invoke(args); + } + + private: + + struct NoMoreRecordedAction : Action { + + + + + + + + virtual R invoke(const ArgumentsTuple &) override { + FAIL("no more recorded actions"); + return R(); + } + + virtual bool isDone() override { + return false; + } + }; + + void append(Action *action) { + std::shared_ptr destructable{action}; + _recordedActions.insert(_recordedActions.end() - 1, destructable); + } + + void clear() { + _recordedActions.clear(); + _usedActions.clear(); + auto actionPtr = std::shared_ptr {new NoMoreRecordedAction()}; + _recordedActions.push_back(actionPtr); + } + + std::vector> _recordedActions; + std::vector> _usedActions; + }; + +} + +namespace fakeit { + + template + class DataMemberStubbingRoot { + private: + + public: + DataMemberStubbingRoot(const DataMemberStubbingRoot &) = default; + + DataMemberStubbingRoot() = default; + + void operator=(const DataType&) { + } + }; + +} +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fakeit { + + struct Xaction { + virtual void commit() = 0; + + virtual ~Xaction() { } + }; +} + +namespace fakeit { + + + template + struct SpyingContext : Xaction { + virtual void appendAction(Action *action) = 0; + + virtual std::function getOriginalMethodCopyArgs() = 0; + virtual std::function getOriginalMethodForwardArgs() = 0; + }; +} +namespace fakeit { + + + template + struct StubbingContext : public Xaction { + virtual void appendAction(Action *action) = 0; + }; +} +#include +#include +#include +#include +#include +#include + + +namespace fakeit { + + template + class MatchersCollector { + + std::vector &_matchers; + + public: + + + template + using ArgType = typename std::tuple_element>::type; + + template + using NakedArgType = typename naked_type>::type; + + template + struct IsMatcherCreatorTypeCompatible : std::false_type {}; + + template + struct IsMatcherCreatorTypeCompatible>::value, void>::type> : std::true_type {}; + + MatchersCollector(std::vector &matchers) + : _matchers(matchers) { + } + + void CollectMatchers() { + } + + template + typename std::enable_if< + !std::is_same::type>::value && + !IsMatcherCreatorTypeCompatible::type>::value && + std::is_constructible, Head&&>::value, void> + ::type CollectMatchers(Head &&value) { + + TypedMatcher> *d = Eq(std::forward(value)).template createMatcher>(); + _matchers.push_back(d); + } + + template + typename std::enable_if< + IsMatcherCreatorTypeCompatible::type>::value, void> + ::type CollectMatchers(Head &&creator) { + TypedMatcher> *d = creator.template createMatcher>(); + _matchers.push_back(d); + } + + template + typename std::enable_if< + std::is_same::type>::value, void> + ::type CollectMatchers(Head &&) { + TypedMatcher> *d = Any().template createMatcher>(); + _matchers.push_back(d); + } + + template + void CollectMatchers(Head &&head, Tail &&... tail) { + CollectMatchers(std::forward(head)); + MatchersCollector c(_matchers); + c.CollectMatchers(std::forward(tail)...); + } + + }; + +} + +namespace fakeit { + + template + class MethodMockingContext : + public Sequence, + public ActualInvocationsSource, + public virtual StubbingContext, + public virtual SpyingContext, + private Invocation::Matcher { + public: + + struct Context : Destructible { + + + virtual typename std::function getOriginalMethodCopyArgs() = 0; + virtual typename std::function getOriginalMethodForwardArgs() = 0; + + virtual std::string getMethodName() = 0; + + virtual void addMethodInvocationHandler(typename ActualInvocation::Matcher *matcher, + ActualInvocationHandler *invocationHandler) = 0; + + virtual void scanActualInvocations(const std::function &)> &scanner) = 0; + + virtual void setMethodDetails(std::string mockName, std::string methodName) = 0; + + virtual bool isOfMethod(MethodInfo &method) = 0; + + virtual ActualInvocationsSource &getInvolvedMock() = 0; + }; + + private: + class Implementation { + + Context *_stubbingContext; + ActionSequence *_recordedActionSequence; + typename ActualInvocation::Matcher *_invocationMatcher; + bool _commited; + + Context &getStubbingContext() const { + return *_stubbingContext; + } + + public: + + Implementation(Context *stubbingContext) + : _stubbingContext(stubbingContext), + _recordedActionSequence(new ActionSequence()), + _invocationMatcher + { + new DefaultInvocationMatcher()}, _commited(false) { + } + + ~Implementation() { + delete _stubbingContext; + if (!_commited) { + + delete _recordedActionSequence; + delete _invocationMatcher; + } + } + + ActionSequence &getRecordedActionSequence() { + return *_recordedActionSequence; + } + + std::string format() const { + std::string s = getStubbingContext().getMethodName(); + s += _invocationMatcher->format(); + return s; + } + + void getActualInvocations(std::unordered_set &into) const { + auto scanner = [&](ActualInvocation &a) { + if (_invocationMatcher->matches(a)) { + into.insert(&a); + } + }; + getStubbingContext().scanActualInvocations(scanner); + } + + + bool matches(Invocation &invocation) { + MethodInfo &actualMethod = invocation.getMethod(); + if (!getStubbingContext().isOfMethod(actualMethod)) { + return false; + } + + ActualInvocation &actualInvocation = dynamic_cast &>(invocation); + return _invocationMatcher->matches(actualInvocation); + } + + void commit() { + getStubbingContext().addMethodInvocationHandler(_invocationMatcher, _recordedActionSequence); + _commited = true; + } + + void appendAction(Action *action) { + getRecordedActionSequence().AppendDo(action); + } + + void setMethodBodyByAssignment(std::function::type...)> method) { + appendAction(new RepeatForever(method)); + commit(); + } + + void setMethodDetails(std::string mockName, std::string methodName) { + getStubbingContext().setMethodDetails(mockName, methodName); + } + + void getInvolvedMocks(std::vector &into) const { + into.push_back(&getStubbingContext().getInvolvedMock()); + } + + typename std::function getOriginalMethodCopyArgs() { + return getStubbingContext().getOriginalMethodCopyArgs(); + } + + typename std::function getOriginalMethodForwardArgs() { + return getStubbingContext().getOriginalMethodForwardArgs(); + } + + void setInvocationMatcher(typename ActualInvocation::Matcher *matcher) { + delete _invocationMatcher; + _invocationMatcher = matcher; + } + }; + + protected: + + MethodMockingContext(Context *stubbingContext) + : _impl{new Implementation(stubbingContext)} { + } + + MethodMockingContext(const MethodMockingContext &) = default; + + + + MethodMockingContext(MethodMockingContext &&other) + : _impl(std::move(other._impl)) { + } + + virtual ~MethodMockingContext() FAKEIT_NO_THROWS { } + + std::string format() const override { + return _impl->format(); + } + + unsigned int size() const override { + return 1; + } + + + void getInvolvedMocks(std::vector &into) const override { + _impl->getInvolvedMocks(into); + } + + void getExpectedSequence(std::vector &into) const override { + const Invocation::Matcher *b = this; + Invocation::Matcher *c = const_cast(b); + into.push_back(c); + } + + + void getActualInvocations(std::unordered_set &into) const override { + _impl->getActualInvocations(into); + } + + + bool matches(Invocation &invocation) override { + return _impl->matches(invocation); + } + + void commit() override { + _impl->commit(); + } + + void setMethodDetails(std::string mockName, std::string methodName) { + _impl->setMethodDetails(mockName, methodName); + } + + void setMatchingCriteria(const std::function& predicate) { + typename ActualInvocation::Matcher *matcher{ + new UserDefinedInvocationMatcher(predicate)}; + _impl->setInvocationMatcher(matcher); + } + + void setMatchingCriteria(std::vector &matchers) { + typename ActualInvocation::Matcher *matcher{ + new ArgumentsMatcherInvocationMatcher(matchers)}; + _impl->setInvocationMatcher(matcher); + } + + + void appendAction(Action *action) override { + _impl->appendAction(action); + } + + void setMethodBodyByAssignment(std::function::type...)> method) { + _impl->setMethodBodyByAssignment(method); + } + + template + typename std::enable_if< + sizeof...(matcherCreators) == sizeof...(arglist), void> + ::type setMatchingCriteria(matcherCreators &&... matcherCreator) { + std::vector matchers; + + MatchersCollector<0, arglist...> c(matchers); + c.CollectMatchers(std::forward(matcherCreator)...); + + MethodMockingContext::setMatchingCriteria(matchers); + } + + private: + + typename std::function getOriginalMethodCopyArgs() override { + return _impl->getOriginalMethodCopyArgs(); + } + + typename std::function getOriginalMethodForwardArgs() override { + return _impl->getOriginalMethodForwardArgs(); + } + + std::shared_ptr _impl; + }; + + template + class MockingContext : + public MethodMockingContext { + MockingContext &operator=(const MockingContext &) = delete; + + public: + + MockingContext(typename MethodMockingContext::Context *stubbingContext) + : MethodMockingContext(stubbingContext) { + } + + MockingContext(const MockingContext &) = default; + + MockingContext(MockingContext &&other) + : MethodMockingContext(std::move(other)) { + } + + MockingContext &setMethodDetails(std::string mockName, std::string methodName) { + MethodMockingContext::setMethodDetails(mockName, methodName); + return *this; + } + + template + MockingContext &Using(arg_matcher &&... arg_matchers) { + MethodMockingContext::setMatchingCriteria(std::forward(arg_matchers)...); + return *this; + } + + MockingContext &Matching(const std::function& matcher) { + MethodMockingContext::setMatchingCriteria(matcher); + return *this; + } + + MockingContext &operator()(const arglist &... args) { + MethodMockingContext::setMatchingCriteria(args...); + return *this; + } + + MockingContext &operator()(const std::function& matcher) { + MethodMockingContext::setMatchingCriteria(matcher); + return *this; + } + + void operator=(std::function method) { + MethodMockingContext::setMethodBodyByAssignment(method); + } + + template + typename std::enable_if::value, void>::type operator=(const R &r) { + auto method = [r](const typename fakeit::test_arg::type...) -> R { return r; }; + MethodMockingContext::setMethodBodyByAssignment(method); + } + + template + typename std::enable_if::value, void>::type operator=(const R &r) { + auto method = [&r](const typename fakeit::test_arg::type...) -> R { return r; }; + MethodMockingContext::setMethodBodyByAssignment(method); + } + }; + + template + class MockingContext : + public MethodMockingContext { + MockingContext &operator=(const MockingContext &) = delete; + + public: + + MockingContext(typename MethodMockingContext::Context *stubbingContext) + : MethodMockingContext(stubbingContext) { + } + + MockingContext(const MockingContext &) = default; + + MockingContext(MockingContext &&other) + : MethodMockingContext(std::move(other)) { + } + + MockingContext &setMethodDetails(std::string mockName, std::string methodName) { + MethodMockingContext::setMethodDetails(mockName, methodName); + return *this; + } + + template + MockingContext &Using(arg_matcher &&... arg_matchers) { + MethodMockingContext::setMatchingCriteria(std::forward(arg_matchers)...); + return *this; + } + + MockingContext &Matching(const std::function& matcher) { + MethodMockingContext::setMatchingCriteria(matcher); + return *this; + } + + MockingContext &operator()(const arglist &... args) { + MethodMockingContext::setMatchingCriteria(args...); + return *this; + } + + MockingContext &operator()(const std::function& matcher) { + MethodMockingContext::setMatchingCriteria(matcher); + return *this; + } + + void operator=(std::function method) { + MethodMockingContext::setMethodBodyByAssignment(method); + } + + }; + + class DtorMockingContext : public MethodMockingContext { + public: + + DtorMockingContext(MethodMockingContext::Context *stubbingContext) + : MethodMockingContext(stubbingContext) { + } + + DtorMockingContext(const DtorMockingContext &other) : MethodMockingContext(other) { + } + + DtorMockingContext(DtorMockingContext &&other) : MethodMockingContext(std::move(other)) { + } + + void operator=(std::function method) { + MethodMockingContext::setMethodBodyByAssignment(method); + } + + DtorMockingContext &setMethodDetails(std::string mockName, std::string methodName) { + MethodMockingContext::setMethodDetails(mockName, methodName); + return *this; + } + }; + +} + +namespace fakeit { + + + template + class MockImpl : private MockObject, public virtual ActualInvocationsSource { + public: + + MockImpl(FakeitContext &fakeit, C &obj) + : MockImpl(fakeit, obj, true) { + } + + MockImpl(FakeitContext &fakeit) + : MockImpl(fakeit, *(createFakeInstance()), false){ + FakeObject *fake = asFakeObject(_instanceOwner.get()); + fake->getVirtualTable().setCookie(1, this); + } + + virtual ~MockImpl() FAKEIT_NO_THROWS { + _proxy.detach(); + } + + + void getActualInvocations(std::unordered_set &into) const override { + std::vector vec; + _proxy.getMethodMocks(vec); + for (ActualInvocationsSource *s : vec) { + s->getActualInvocations(into); + } + } + + void initDataMembersIfOwner() + { + if (isOwner()) { + FakeObject *fake = asFakeObject(_instanceOwner.get()); + fake->initializeDataMembersArea(); + } + } + + void reset() { + _proxy.Reset(); + initDataMembersIfOwner(); + } + + void clear() + { + std::vector vec; + _proxy.getMethodMocks(vec); + for (ActualInvocationsContainer *s : vec) { + s->clear(); + } + initDataMembersIfOwner(); + } + + virtual C &get() override { + return _proxy.get(); + } + + virtual FakeitContext &getFakeIt() override { + return _fakeit; + } + + template::value>::type> + DataMemberStubbingRoot stubDataMember(DataType T::*member, const arglist &... ctorargs) { + _proxy.stubDataMember(member, ctorargs...); + return DataMemberStubbingRoot(); + } + + template::value>::type> + MockingContext stubMethod(R(T::*vMethod)(arglist...)) { + return MockingContext(new UniqueMethodMockingContextImpl < id, R, arglist... > + (*this, vMethod)); + } + + DtorMockingContext stubDtor() { + return DtorMockingContext(new DtorMockingContextImpl(*this)); + } + + + + + + + + private: + + + + + + + + + + std::shared_ptr> _instanceOwner; + DynamicProxy _proxy; + FakeitContext &_fakeit; + + MockImpl(FakeitContext &fakeit, C &obj, bool isSpy) + : _instanceOwner(isSpy ? nullptr : asFakeObject(&obj)) + , _proxy{obj} + , _fakeit(fakeit) {} + + static FakeObject* asFakeObject(void* instance){ + return reinterpret_cast *>(instance); + } + + template + class MethodMockingContextBase : public MethodMockingContext::Context { + protected: + MockImpl &_mock; + + virtual RecordedMethodBody &getRecordedMethodBody() = 0; + + public: + MethodMockingContextBase(MockImpl &mock) : _mock(mock) { } + + virtual ~MethodMockingContextBase() = default; + + void addMethodInvocationHandler(typename ActualInvocation::Matcher *matcher, + ActualInvocationHandler *invocationHandler) { + getRecordedMethodBody().addMethodInvocationHandler(matcher, invocationHandler); + } + + void scanActualInvocations(const std::function &)> &scanner) { + getRecordedMethodBody().scanActualInvocations(scanner); + } + + void setMethodDetails(std::string mockName, std::string methodName) { + getRecordedMethodBody().setMethodDetails(mockName, methodName); + } + + bool isOfMethod(MethodInfo &method) { + return getRecordedMethodBody().isOfMethod(method); + } + + ActualInvocationsSource &getInvolvedMock() { + return _mock; + } + + std::string getMethodName() { + return getRecordedMethodBody().getMethod().name(); + } + + }; + + template + class MethodMockingContextImpl : public MethodMockingContextBase { + protected: + + R (C::*_vMethod)(arglist...); + + public: + virtual ~MethodMockingContextImpl() = default; + + MethodMockingContextImpl(MockImpl &mock, R (C::*vMethod)(arglist...)) + : MethodMockingContextBase(mock), _vMethod(vMethod) { + } + + template::value...>::value, int>::type = 0> + std::function getOriginalMethodCopyArgsInternal(int) { + auto mPtr = _vMethod; + auto& mock = MethodMockingContextBase::_mock; + C * instance = &(MethodMockingContextBase::_mock.get()); + return [=, &mock](arglist&... args) -> R { + auto methodSwapper = mock.createRaiiMethodSwapper(mPtr); + return (instance->*mPtr)(args...); + }; + } + + + template + [[noreturn]] std::function getOriginalMethodCopyArgsInternal(long) { + std::abort(); + } + + + std::function getOriginalMethodCopyArgs() override { + return getOriginalMethodCopyArgsInternal(0); + } + + std::function getOriginalMethodForwardArgs() override { + auto mPtr = _vMethod; + auto& mock = MethodMockingContextBase::_mock; + C * instance = &(MethodMockingContextBase::_mock.get()); + return [=, &mock](arglist&... args) -> R { + auto methodSwapper = mock.createRaiiMethodSwapper(mPtr); + return (instance->*mPtr)(std::forward(args)...); + }; + } + }; + + + template + class UniqueMethodMockingContextImpl : public MethodMockingContextImpl { + protected: + + virtual RecordedMethodBody &getRecordedMethodBody() override { + return MethodMockingContextBase::_mock.template stubMethodIfNotStubbed( + MethodMockingContextBase::_mock._proxy, + MethodMockingContextImpl::_vMethod); + } + + public: + + UniqueMethodMockingContextImpl(MockImpl &mock, R (C::*vMethod)(arglist...)) + : MethodMockingContextImpl(mock, vMethod) { + } + }; + + class DtorMockingContextImpl : public MethodMockingContextBase { + + protected: + + virtual RecordedMethodBody &getRecordedMethodBody() override { + return MethodMockingContextBase::_mock.stubDtorIfNotStubbed( + MethodMockingContextBase::_mock._proxy); + } + + public: + virtual ~DtorMockingContextImpl() = default; + + DtorMockingContextImpl(MockImpl &mock) + : MethodMockingContextBase(mock) { + } + + std::function getOriginalMethodCopyArgs() override { + return [=]() -> void { + }; + } + + std::function getOriginalMethodForwardArgs() override { + return [=]() -> void { + }; + } + + }; + + static MockImpl *getMockImpl(void *instance) { + FakeObject *fake = asFakeObject(instance); + MockImpl *mock = reinterpret_cast *>(fake->getVirtualTable().getCookie( + 1)); + return mock; + } + + bool isOwner(){ return _instanceOwner != nullptr;} + + void unmockedDtor() {} + + void unmocked() { + ActualInvocation<> invocation(Invocation::nextInvocationOrdinal(), UnknownMethod::instance()); + UnexpectedMethodCallEvent event(UnexpectedType::Unmocked, invocation); + auto &fakeit = getMockImpl(this)->_fakeit; + fakeit.handle(event); + + std::string format = fakeit.format(event); + FAIL(format); + } + + static C *createFakeInstance() { + FakeObject *fake = new FakeObject(); + void *unmockedMethodStubPtr = union_cast(&MockImpl::unmocked); + void *unmockedDtorStubPtr = union_cast(&MockImpl::unmockedDtor); + fake->getVirtualTable().initAll(unmockedMethodStubPtr); + if (VTUtils::hasVirtualDestructor()) + fake->setDtor(unmockedDtorStubPtr); + return reinterpret_cast(fake); + } + + template + Finally createRaiiMethodSwapper(R(C::*vMethod)(arglist...)) { + return _proxy.createRaiiMethodSwapper(vMethod); + } + + template + void *getOriginalMethod(R (C::*vMethod)(arglist...)) { + auto vt = _proxy.getOriginalVT(); + auto offset = VTUtils::getOffset(vMethod); + void *origMethodPtr = vt.getMethod(offset); + return origMethodPtr; + } + + void *getOriginalDtor() { + auto vt = _proxy.getOriginalVT(); + auto offset = VTUtils::getDestructorOffset(); + void *origMethodPtr = vt.getMethod(offset); + return origMethodPtr; + } + + template + RecordedMethodBody &stubMethodIfNotStubbed(DynamicProxy &proxy, + R (C::*vMethod)(arglist...)) { + if (!proxy.isMethodStubbed(vMethod)) { + proxy.template stubMethod(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod)); + } + Destructible *d = proxy.getMethodMock(vMethod); + RecordedMethodBody *methodMock = dynamic_cast *>(d); + return *methodMock; + } + + RecordedMethodBody &stubDtorIfNotStubbed(DynamicProxy &proxy) { + if (!proxy.isDtorStubbed()) { + proxy.stubDtor(createRecordedDtorBody(*this)); + } + Destructible *d = proxy.getDtorMock(); + RecordedMethodBody *dtorMock = dynamic_cast *>(d); + return *dtorMock; + } + + template + static RecordedMethodBody *createRecordedMethodBody(MockObject &mock, + R(C::*vMethod)(arglist...)) { + return new RecordedMethodBody(mock.getFakeIt(), typeid(vMethod).name()); + } + + static RecordedMethodBody *createRecordedDtorBody(MockObject &mock) { + return new RecordedMethodBody(mock.getFakeIt(), "dtor"); + } + }; +} +namespace fakeit { + + template + struct Prototype; + + template + struct Prototype { + + template + struct MemberType { + + using Type = R (C::*)(Args...); + using ConstType = R (C::*)(Args...) const; + using RefType = R (C::*)(Args...) &; + using ConstRefType = R (C::*)(Args...) const&; + using RValRefType = R (C::*)(Args...) &&; + using ConstRValRefType = R (C::*)(Args...) const&&; + + static Type get(Type t) { + return t; + } + + static ConstType getConst(ConstType t) { + return t; + } + + static RefType getRef(RefType t) { + return t; + } + + static ConstRefType getConstRef(ConstRefType t) { + return t; + } + + static RValRefType getRValRef(RValRefType t) { + return t; + } + + static ConstRValRefType getConstRValRef(ConstRValRefType t) { + return t; + } + + }; + + }; + + template + struct UniqueMethod { + R (C::*method)(arglist...); + + UniqueMethod(R (C::*vMethod)(arglist...)) : method(vMethod) { } + + int uniqueId() { + return X; + } + + + + + }; + +} + +namespace fakeit { + namespace internal { + template + struct WithCommonVoid { + using type = T; + }; + + + + + + template + struct WithCommonVoid::value, void>::type> { + using type = void; + }; + + template + using WithCommonVoid_t = typename WithCommonVoid::type; + } + + template + class Mock : public ActualInvocationsSource { + MockImpl impl; + public: + virtual ~Mock() = default; + + static_assert(std::is_polymorphic::value, "Can only mock a polymorphic type"); + + Mock() : impl(Fakeit) { + } + + explicit Mock(C &obj) : impl(Fakeit, obj) { + } + + virtual C &get() { + return impl.get(); + } + + + + + + C &operator()() { + return get(); + } + + void Reset() { + impl.reset(); + } + + void ClearInvocationHistory() { + impl.clear(); + } + + template::value>::type> + DataMemberStubbingRoot Stub(DataType C::* member, const arglist &... ctorargs) { + return impl.stubDataMember(member, ctorargs...); + } + + + template::value>::type> + MockingContext, arglist...> stub(R (T::*vMethod)(arglist...) const) { + auto methodWithoutConstVolatile = reinterpret_cast (T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + + template::value>::type> + MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) volatile) { + auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + + template::value>::type> + MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) { + auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + + template::value>::type> + MockingContext, arglist...> stub(R(T::*vMethod)(arglist...)) { + auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + + template::value>::type> + MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) &) { + auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + + template::value>::type> + MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) const&) { + auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + + template::value>::type> + MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) &&) { + auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + + template::value>::type> + MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) const&&) { + auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); + return impl.template stubMethod(methodWithoutConstVolatile); + } + + DtorMockingContext dtor() { + return impl.stubDtor(); + } + + void getActualInvocations(std::unordered_set &into) const override { + impl.getActualInvocations(into); + } + + }; + +} + +#include + +namespace fakeit { + + class RefCount { + private: + int count; + + public: + void AddRef() { + count++; + } + + int Release() { + return --count; + } + }; + + template + class smart_ptr { + private: + T *pData; + RefCount *reference; + + public: + smart_ptr() : pData(0), reference(0) { + reference = new RefCount(); + reference->AddRef(); + } + + smart_ptr(T *pValue) : pData(pValue), reference(0) { + reference = new RefCount(); + reference->AddRef(); + } + + smart_ptr(const smart_ptr &sp) : pData(sp.pData), reference(sp.reference) { + reference->AddRef(); + } + + ~smart_ptr() FAKEIT_THROWS { + if (reference->Release() == 0) { + delete reference; + delete pData; + } + } + + T &operator*() { + return *pData; + } + + T *operator->() { + return pData; + } + + smart_ptr &operator=(const smart_ptr &sp) { + if (this != &sp) { + + + if (reference->Release() == 0) { + delete reference; + delete pData; + } + + + + pData = sp.pData; + reference = sp.reference; + reference->AddRef(); + } + return *this; + } + }; + +} + +namespace fakeit { + + class WhenFunctor { + + struct StubbingChange { + + friend class WhenFunctor; + + virtual ~StubbingChange() FAKEIT_THROWS { + + if (UncaughtException()) { + return; + } + + _xaction.commit(); + } + + StubbingChange(const StubbingChange &other) : + _xaction(other._xaction) { + } + + private: + + StubbingChange(Xaction &xaction) + : _xaction(xaction) { + } + + Xaction &_xaction; + }; + + public: + + template + struct MethodProgress : MethodStubbingProgress { + + friend class WhenFunctor; + + virtual ~MethodProgress() override = default; + + MethodProgress(const MethodProgress &other) : + _progress(other._progress), _context(other._context) { + } + + MethodProgress(StubbingContext &xaction) : + _progress(new StubbingChange(xaction)), _context(xaction) { + } + + protected: + + virtual MethodStubbingProgress &DoImpl(Action *action) override { + _context.appendAction(action); + return *this; + } + + private: + smart_ptr _progress; + StubbingContext &_context; + }; + + + WhenFunctor() { + } + + template + MethodProgress operator()(const StubbingContext &stubbingContext) { + StubbingContext &rootWithoutConst = const_cast &>(stubbingContext); + MethodProgress progress(rootWithoutConst); + return progress; + } + + }; + +} +namespace fakeit { + + class FakeFunctor { + private: + template + void fake(const StubbingContext &root) { + StubbingContext &rootWithoutConst = const_cast &>(root); + rootWithoutConst.appendAction(new ReturnDefaultValue()); + rootWithoutConst.commit(); + } + + void operator()() { + } + + public: + + template + void operator()(const H &head, const M &... tail) { + fake(head); + this->operator()(tail...); + } + + }; + +} +#include +#include + + +namespace fakeit { + + struct InvocationUtils { + + static void sortByInvocationOrder(std::unordered_set &ivocations, + std::vector &result) { + auto comparator = [](Invocation *a, Invocation *b) -> bool { + return a->getOrdinal() < b->getOrdinal(); + }; + std::set sortedIvocations(comparator); + for (auto i : ivocations) + sortedIvocations.insert(i); + + for (auto i : sortedIvocations) + result.push_back(i); + } + + static void collectActualInvocations(std::unordered_set &actualInvocations, + std::vector &invocationSources) { + for (auto source : invocationSources) { + source->getActualInvocations(actualInvocations); + } + } + + static void selectNonVerifiedInvocations(std::unordered_set &actualInvocations, + std::unordered_set &into) { + for (auto invocation : actualInvocations) { + if (!invocation->isVerified()) { + into.insert(invocation); + } + } + } + + static void collectInvocationSources(std::vector &) { + } + + template + static void collectInvocationSources(std::vector &into, + const ActualInvocationsSource &mock, + const list &... tail) { + into.push_back(const_cast(&mock)); + collectInvocationSources(into, tail...); + } + + static void collectSequences(std::vector &) { + } + + template + static void collectSequences(std::vector &vec, const Sequence &sequence, const list &... tail) { + vec.push_back(&const_cast(sequence)); + collectSequences(vec, tail...); + } + + static void collectInvolvedMocks(std::vector &allSequences, + std::vector &involvedMocks) { + for (auto sequence : allSequences) { + sequence->getInvolvedMocks(involvedMocks); + } + } + + template + static T &remove_const(const T &s) { + return const_cast(s); + } + + }; + +} + +#include + +#include +#include + +namespace fakeit { + struct MatchAnalysis { + std::vector actualSequence; + std::vector matchedInvocations; + int count; + + void run(InvocationsSourceProxy &involvedInvocationSources, std::vector &expectedPattern) { + getActualInvocationSequence(involvedInvocationSources, actualSequence); + count = countMatches(expectedPattern, actualSequence, matchedInvocations); + } + + private: + static void getActualInvocationSequence(InvocationsSourceProxy &involvedMocks, + std::vector &actualSequence) { + std::unordered_set actualInvocations; + collectActualInvocations(involvedMocks, actualInvocations); + InvocationUtils::sortByInvocationOrder(actualInvocations, actualSequence); + } + + static int countMatches(std::vector &pattern, std::vector &actualSequence, + std::vector &matchedInvocations) { + int end = -1; + int count = 0; + int startSearchIndex = 0; + while (findNextMatch(pattern, actualSequence, startSearchIndex, end, matchedInvocations)) { + count++; + startSearchIndex = end; + } + return count; + } + + static void collectActualInvocations(InvocationsSourceProxy &involvedMocks, + std::unordered_set &actualInvocations) { + involvedMocks.getActualInvocations(actualInvocations); + } + + static bool findNextMatch(std::vector &pattern, std::vector &actualSequence, + int startSearchIndex, int &end, + std::vector &matchedInvocations) { + for (auto sequence : pattern) { + int index = findNextMatch(sequence, actualSequence, startSearchIndex); + if (index == -1) { + return false; + } + collectMatchedInvocations(actualSequence, matchedInvocations, index, sequence->size()); + startSearchIndex = index + sequence->size(); + } + end = startSearchIndex; + return true; + } + + + static void collectMatchedInvocations(std::vector &actualSequence, + std::vector &matchedInvocations, int start, + int length) { + int indexAfterMatchedPattern = start + length; + for (; start < indexAfterMatchedPattern; start++) { + matchedInvocations.push_back(actualSequence[start]); + } + } + + + static bool isMatch(std::vector &actualSequence, + std::vector &expectedSequence, int start) { + bool found = true; + for (unsigned int j = 0; found && j < expectedSequence.size(); j++) { + Invocation *actual = actualSequence[start + j]; + Invocation::Matcher *expected = expectedSequence[j]; + found = found && expected->matches(*actual); + } + return found; + } + + static int findNextMatch(Sequence *&pattern, std::vector &actualSequence, int startSearchIndex) { + std::vector expectedSequence; + pattern->getExpectedSequence(expectedSequence); + for (int i = startSearchIndex; i < ((int) actualSequence.size() - (int) expectedSequence.size() + 1); i++) { + if (isMatch(actualSequence, expectedSequence, i)) { + return i; + } + } + return -1; + } + + }; +} + +namespace fakeit { + + struct SequenceVerificationExpectation { + + friend class SequenceVerificationProgress; + + ~SequenceVerificationExpectation() FAKEIT_THROWS { + if (UncaughtException()) { + return; + } + VerifyExpectation(_fakeit); + } + + void setExpectedPattern(std::vector expectedPattern) { + _expectedPattern = expectedPattern; + } + + void setExpectedCount(const int count) { + _expectedCount = count; + } + + void expectAnything() { + _expectAnything = true; + } + + void setFileInfo(const char * file, int line, const char * callingMethod) { + _file = file; + _line = line; + _testMethod = callingMethod; + } + + private: + + VerificationEventHandler &_fakeit; + InvocationsSourceProxy _involvedInvocationSources; + std::vector _expectedPattern; + int _expectedCount; + bool _expectAnything; + + const char * _file; + int _line; + const char * _testMethod; + bool _isVerified; + + SequenceVerificationExpectation( + VerificationEventHandler &fakeit, + InvocationsSourceProxy mocks, + std::vector &expectedPattern) : + _fakeit(fakeit), + _involvedInvocationSources(mocks), + _expectedPattern(expectedPattern), + _expectedCount(-1), + _expectAnything(false), + _line(0), + _isVerified(false) { + } + + + void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) { + if (_isVerified) + return; + _isVerified = true; + + MatchAnalysis ma; + ma.run(_involvedInvocationSources, _expectedPattern); + + if (isNotAnythingVerification()) { + if (isAtLeastVerification() && atLeastLimitNotReached(ma.count)) { + return handleAtLeastVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count); + } + + if (isExactVerification() && exactLimitNotMatched(ma.count)) { + return handleExactVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count); + } + } + + markAsVerified(ma.matchedInvocations); + } + + std::vector &collectSequences(std::vector &vec) { + return vec; + } + + template + std::vector &collectSequences(std::vector &vec, const Sequence &sequence, + const list &... tail) { + vec.push_back(&const_cast(sequence)); + return collectSequences(vec, tail...); + } + + + static void markAsVerified(std::vector &matchedInvocations) { + for (auto i : matchedInvocations) { + i->markAsVerified(); + } + } + + bool isNotAnythingVerification() { + return !_expectAnything; + } + + bool isAtLeastVerification() { + + return _expectedCount < 0; + } + + bool isExactVerification() { + return !isAtLeastVerification(); + } + + bool atLeastLimitNotReached(int actualCount) { + return actualCount < -_expectedCount; + } + + bool exactLimitNotMatched(int actualCount) { + return actualCount != _expectedCount; + } + + void handleExactVerificationEvent(VerificationEventHandler &verificationErrorHandler, + std::vector actualSequence, int count) { + SequenceVerificationEvent evt(VerificationType::Exact, _expectedPattern, actualSequence, _expectedCount, + count); + evt.setFileInfo(_file, _line, _testMethod); + return verificationErrorHandler.handle(evt); + } + + void handleAtLeastVerificationEvent(VerificationEventHandler &verificationErrorHandler, + std::vector actualSequence, int count) { + SequenceVerificationEvent evt(VerificationType::AtLeast, _expectedPattern, actualSequence, -_expectedCount, + count); + evt.setFileInfo(_file, _line, _testMethod); + return verificationErrorHandler.handle(evt); + } + + }; + +} +namespace fakeit { + class FalseEventHandler : public VerificationEventHandler { + + void handle(const SequenceVerificationEvent &) override { + handle_result = false; + } + + void handle(const NoMoreInvocationsVerificationEvent &) override { + handle_result = false; + } + + public: + bool handle_result = true; + }; +} + + +namespace fakeit { + + struct FakeitContext; + + class SequenceVerificationProgress { + + friend class UsingFunctor; + + friend class VerifyFunctor; + + friend class UsingProgress; + + smart_ptr _expectationPtr; + + SequenceVerificationProgress(SequenceVerificationExpectation *ptr) : _expectationPtr(ptr) { + } + + SequenceVerificationProgress( + FakeitContext &fakeit, + InvocationsSourceProxy sources, + std::vector &allSequences) : + SequenceVerificationProgress(new SequenceVerificationExpectation(fakeit, sources, allSequences)) { + } + + virtual void verifyInvocations(const int times) { + _expectationPtr->setExpectedCount(times); + } + + class Terminator { + smart_ptr _expectationPtr; + + bool toBool() { + FalseEventHandler eh; + _expectationPtr->VerifyExpectation(eh); + return eh.handle_result; + } + + public: + Terminator(smart_ptr expectationPtr) : _expectationPtr(expectationPtr) { }; + + operator bool() { + return toBool(); + } + + bool operator!() const { return !const_cast(this)->toBool(); } + }; + + public: + + virtual ~SequenceVerificationProgress() FAKEIT_THROWS { }; + + operator bool() const { + return Terminator(_expectationPtr); + } + + bool operator!() const { return !Terminator(_expectationPtr); } + + Terminator Any() { + _expectationPtr->expectAnything(); + return Terminator(_expectationPtr); + } + + Terminator Never() { + Exactly(0); + return Terminator(_expectationPtr); + } + + Terminator Once() { + Exactly(1); + return Terminator(_expectationPtr); + } + + Terminator Twice() { + Exactly(2); + return Terminator(_expectationPtr); + } + + Terminator AtLeastOnce() { + verifyInvocations(-1); + return Terminator(_expectationPtr); + } + + Terminator Exactly(const int times) { + if (times < 0) { + FAIL(std::string("bad argument times:").append(fakeit::to_string(times))); + } + verifyInvocations(times); + return Terminator(_expectationPtr); + } + + Terminator Exactly(const Quantity &q) { + Exactly(q.quantity); + return Terminator(_expectationPtr); + } + + Terminator AtLeast(const int times) { + if (times < 0) { + FAIL(std::string("bad argument times:").append(fakeit::to_string(times))); + } + verifyInvocations(-times); + return Terminator(_expectationPtr); + } + + Terminator AtLeast(const Quantity &q) { + AtLeast(q.quantity); + return Terminator(_expectationPtr); + } + + SequenceVerificationProgress setFileInfo(const char * file, int line, const char * callingMethod) { + _expectationPtr->setFileInfo(file, line, callingMethod); + return *this; + } + }; +} + +namespace fakeit { + + class UsingProgress { + fakeit::FakeitContext &_fakeit; + InvocationsSourceProxy _sources; + + void collectSequences(std::vector &) { + } + + template + void collectSequences(std::vector &vec, const fakeit::Sequence &sequence, + const list &... tail) { + vec.push_back(&const_cast(sequence)); + collectSequences(vec, tail...); + } + + public: + + UsingProgress(fakeit::FakeitContext &fakeit, InvocationsSourceProxy source) : + _fakeit(fakeit), + _sources(source) { + } + + template + SequenceVerificationProgress Verify(const fakeit::Sequence &sequence, const list &... tail) { + std::vector allSequences; + collectSequences(allSequences, sequence, tail...); + SequenceVerificationProgress progress(_fakeit, _sources, allSequences); + return progress; + } + + }; +} + +namespace fakeit { + + class UsingFunctor { + + friend class VerifyFunctor; + + FakeitContext &_fakeit; + + public: + + UsingFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { + } + + template + UsingProgress operator()(const ActualInvocationsSource &head, const list &... tail) { + std::vector allMocks{&InvocationUtils::remove_const(head), + &InvocationUtils::remove_const(tail)...}; + InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)}; + UsingProgress progress(_fakeit, aggregateInvocationsSource); + return progress; + } + + }; +} +#include + +namespace fakeit { + + class VerifyFunctor { + + FakeitContext &_fakeit; + + + public: + + VerifyFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { + } + + template + SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) { + std::vector allSequences{&InvocationUtils::remove_const(sequence), + &InvocationUtils::remove_const(tail)...}; + + std::vector involvedSources; + InvocationUtils::collectInvolvedMocks(allSequences, involvedSources); + InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)}; + + UsingProgress usingProgress(_fakeit, aggregateInvocationsSource); + return usingProgress.Verify(sequence, tail...); + } + + }; + +} +#include +#include +namespace fakeit { + + class VerifyNoOtherInvocationsVerificationProgress { + + friend class VerifyNoOtherInvocationsFunctor; + + struct VerifyNoOtherInvocationsExpectation { + + friend class VerifyNoOtherInvocationsVerificationProgress; + + ~VerifyNoOtherInvocationsExpectation() FAKEIT_THROWS { + if (UncaughtException()) { + return; + } + + VerifyExpectation(_fakeit); + } + + void setFileInfo(const char * file, int line, const char * callingMethod) { + _file = file; + _line = line; + _callingMethod = callingMethod; + } + + private: + + VerificationEventHandler &_fakeit; + std::vector _mocks; + + const char * _file; + int _line; + const char * _callingMethod; + bool _isVerified; + + VerifyNoOtherInvocationsExpectation(VerificationEventHandler &fakeit, + std::vector mocks) : + _fakeit(fakeit), + _mocks(mocks), + _line(0), + _isVerified(false) { + } + + VerifyNoOtherInvocationsExpectation(const VerifyNoOtherInvocationsExpectation &other) = default; + + void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) { + if (_isVerified) + return; + _isVerified = true; + + std::unordered_set actualInvocations; + InvocationUtils::collectActualInvocations(actualInvocations, _mocks); + + std::unordered_set nonVerifiedInvocations; + InvocationUtils::selectNonVerifiedInvocations(actualInvocations, nonVerifiedInvocations); + + if (nonVerifiedInvocations.size() > 0) { + std::vector sortedNonVerifiedInvocations; + InvocationUtils::sortByInvocationOrder(nonVerifiedInvocations, sortedNonVerifiedInvocations); + + std::vector sortedActualInvocations; + InvocationUtils::sortByInvocationOrder(actualInvocations, sortedActualInvocations); + + NoMoreInvocationsVerificationEvent evt(sortedActualInvocations, sortedNonVerifiedInvocations); + evt.setFileInfo(_file, _line, _callingMethod); + return verificationErrorHandler.handle(evt); + } + } + + }; + + fakeit::smart_ptr _ptr; + + VerifyNoOtherInvocationsVerificationProgress(VerifyNoOtherInvocationsExpectation *ptr) : + _ptr(ptr) { + } + + VerifyNoOtherInvocationsVerificationProgress(FakeitContext &fakeit, + std::vector &invocationSources) + : VerifyNoOtherInvocationsVerificationProgress( + new VerifyNoOtherInvocationsExpectation(fakeit, invocationSources) + ) { + } + + bool toBool() { + FalseEventHandler ev; + _ptr->VerifyExpectation(ev); + return ev.handle_result; + } + + public: + + + ~VerifyNoOtherInvocationsVerificationProgress() FAKEIT_THROWS { + }; + + VerifyNoOtherInvocationsVerificationProgress setFileInfo(const char * file, int line, + const char * callingMethod) { + _ptr->setFileInfo(file, line, callingMethod); + return *this; + } + + operator bool() const { + return const_cast(this)->toBool(); + } + + bool operator!() const { return !const_cast(this)->toBool(); } + + }; + +} + + +namespace fakeit { + class VerifyNoOtherInvocationsFunctor { + + FakeitContext &_fakeit; + + public: + + VerifyNoOtherInvocationsFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { + } + + void operator()() { + } + + template + VerifyNoOtherInvocationsVerificationProgress operator()(const ActualInvocationsSource &head, + const list &... tail) { + std::vector invocationSources{&InvocationUtils::remove_const(head), + &InvocationUtils::remove_const(tail)...}; + VerifyNoOtherInvocationsVerificationProgress progress{_fakeit, invocationSources}; + return progress; + } + }; + +} +#include + + +namespace fakeit { + + class SpyFunctor { + private: + + template::value...>::value, int>::type = 0> + void spy(const SpyingContext &root, int) { + SpyingContext &rootWithoutConst = const_cast &>(root); + auto methodFromOriginalVT = rootWithoutConst.getOriginalMethodCopyArgs(); + rootWithoutConst.appendAction(new ReturnDelegateValue(methodFromOriginalVT)); + rootWithoutConst.commit(); + } + + template + void spy(const SpyingContext &, long) { + static_assert(!std::is_same::value, "Spy() cannot accept move-only args, use SpyWithoutVerify() instead which is able to forward these args but then they won't be available for Verify()."); + } + + void operator()() { + } + + public: + + template + void operator()(const H &head, const M &... tail) { + spy(head, 0); + this->operator()(tail...); + } + + }; + +} + +namespace fakeit { + + class SpyWithoutVerifyFunctor { + private: + + template + void spy(const SpyingContext &root) { + SpyingContext &rootWithoutConst = const_cast &>(root); + auto methodFromOriginalVT = rootWithoutConst.getOriginalMethodForwardArgs(); + rootWithoutConst.appendAction(new ReturnDelegateValue(methodFromOriginalVT)); + rootWithoutConst.commit(); + } + + void operator()() { + } + + public: + + template + void operator()(const H &head, const M &... tail) { + spy(head); + this->operator()(tail...); + } + + }; + +} +#include +#include + +namespace fakeit { + class VerifyUnverifiedFunctor { + + FakeitContext &_fakeit; + + public: + + VerifyUnverifiedFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { + } + + template + SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) { + std::vector allSequences{&InvocationUtils::remove_const(sequence), + &InvocationUtils::remove_const(tail)...}; + + std::vector involvedSources; + InvocationUtils::collectInvolvedMocks(allSequences, involvedSources); + + InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)}; + InvocationsSourceProxy unverifiedInvocationsSource{ + new UnverifiedInvocationsSource(aggregateInvocationsSource)}; + + UsingProgress usingProgress(_fakeit, unverifiedInvocationsSource); + return usingProgress.Verify(sequence, tail...); + } + + }; + + class UnverifiedFunctor { + public: + UnverifiedFunctor(FakeitContext &fakeit) : Verify(fakeit) { + } + + VerifyUnverifiedFunctor Verify; + + template + UnverifiedInvocationsSource operator()(const ActualInvocationsSource &head, const list &... tail) { + std::vector allMocks{&InvocationUtils::remove_const(head), + &InvocationUtils::remove_const(tail)...}; + InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)}; + UnverifiedInvocationsSource unverifiedInvocationsSource{aggregateInvocationsSource}; + return unverifiedInvocationsSource; + } + + + + + + + + + + + + + + }; +} +/* clang-format off */ +namespace fakeit { + + static UsingFunctor Using(Fakeit); + static VerifyFunctor Verify(Fakeit); + static VerifyNoOtherInvocationsFunctor VerifyNoOtherInvocations(Fakeit); + static UnverifiedFunctor Unverified(Fakeit); + static SpyFunctor Spy; + static SpyWithoutVerifyFunctor SpyWithoutVerify; + static FakeFunctor Fake; + static WhenFunctor When; + + template + class SilenceUnusedVariableWarnings { + + void use(void *) { + } + + SilenceUnusedVariableWarnings() { + use(&Fake); + use(&When); + use(&Spy); + use(&SpyWithoutVerify); + use(&Using); + use(&Verify); + use(&VerifyNoOtherInvocations); + use(&_); + } + }; +} +/* clang-format on */ +#ifdef _MSC_VER +#define __func__ __FUNCTION__ +#endif + +#define MOCK_TYPE(mock) \ + std::remove_reference::type + +#define OVERLOADED_METHOD_PTR(mock, method, prototype) \ + fakeit::Prototype::template MemberType::get(&MOCK_TYPE(mock)::method) + +#define CONST_OVERLOADED_METHOD_PTR(mock, method, prototype) \ + fakeit::Prototype::template MemberType::getConst(&MOCK_TYPE(mock)::method) + +#define REF_OVERLOADED_METHOD_PTR(mock, method, prototype) \ + fakeit::Prototype::MemberType::getRef(&MOCK_TYPE(mock)::method) + +#define CONST_REF_OVERLOADED_METHOD_PTR(mock, method, prototype) \ + fakeit::Prototype::MemberType::getConstRef(&MOCK_TYPE(mock)::method) + +#define R_VAL_REF_OVERLOADED_METHOD_PTR(mock, method, prototype) \ + fakeit::Prototype::MemberType::getRValRef(&MOCK_TYPE(mock)::method) + +#define CONST_R_VAL_REF_OVERLOADED_METHOD_PTR(mock, method, prototype) \ + fakeit::Prototype::MemberType::getConstRValRef(&MOCK_TYPE(mock)::method) + +#define Dtor(mock) \ + (mock).dtor().setMethodDetails(#mock,"destructor") + +#define Method(mock, method) \ + (mock).template stub<__COUNTER__>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method) + +#define OverloadedMethod(mock, method, prototype) \ + (mock).template stub<__COUNTER__>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + +#define ConstOverloadedMethod(mock, method, prototype) \ + (mock).template stub<__COUNTER__>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + +#define RefOverloadedMethod(mock, method, prototype) \ + (mock).template stub<__COUNTER__>(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + +#define ConstRefOverloadedMethod(mock, method, prototype) \ + (mock).template stub<__COUNTER__>(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + +#define RValRefOverloadedMethod(mock, method, prototype) \ + (mock).template stub<__COUNTER__>(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + +#define ConstRValRefOverloadedMethod(mock, method, prototype) \ + (mock).template stub<__COUNTER__>(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + +#define Verify(...) \ + Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__) + +#define Using(...) \ + Using( __VA_ARGS__ ) + +#define VerifyNoOtherInvocations(...) \ + VerifyNoOtherInvocations( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__) + +#define Fake(...) \ + Fake( __VA_ARGS__ ) + +#define When(call) \ + When(call) + +#endif