TO EDIT : adding mockito folder into 3rdparty folder (zanshin style)
diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/3rdparty/CMakeLists.txt
diff --git a/3rdparty/mockitopp/LICENSE b/3rdparty/mockitopp/LICENSE
new file mode 100644
index 0000000..d4b2da5
--- /dev/null
+++ b/3rdparty/mockitopp/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2008 Trevor Pounds
+
+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/3rdparty/mockitopp/detail/m4/COMMA_IF.m4 b/3rdparty/mockitopp/detail/m4/COMMA_IF.m4
new file mode 100644
index 0000000..0e70e3a
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/COMMA_IF.m4
@@ -0,0 +1 @@
+define(`M4_COMMA_IF', `ifelse(eval($1 > 0), 1, `, ', `')')dnl
diff --git a/3rdparty/mockitopp/detail/m4/ENUM_BINARY_PARAMS.m4 b/3rdparty/mockitopp/detail/m4/ENUM_BINARY_PARAMS.m4
new file mode 100644
index 0000000..9600974
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/ENUM_BINARY_PARAMS.m4
@@ -0,0 +1,3 @@
+include(`mockitopp/detail/m4/COMMA_IF.m4')dnl
+define(`M4_CHECK_INTERCEPT', `ifelse(`$1', `M4_INTERCEPT', `', `$2')')dnl
+define(`M4_ENUM_BINARY_PARAMS', `ifelse(eval($1 > 0), 1, `M4_ENUM_BINARY_PARAMS(decr($1), $2, $3, $4)M4_COMMA_IF(decr($1))`$2'decr($1) `$3'M4_CHECK_INTERCEPT($4, decr($1))', `')')dnl
diff --git a/3rdparty/mockitopp/detail/m4/ENUM_PARAMS.m4 b/3rdparty/mockitopp/detail/m4/ENUM_PARAMS.m4
new file mode 100644
index 0000000..6cb8d6b
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/ENUM_PARAMS.m4
@@ -0,0 +1,2 @@
+include(`mockitopp/detail/m4/COMMA_IF.m4')dnl
+define(`M4_ENUM_PARAMS', `ifelse(eval($1 > 0), 1, `M4_ENUM_PARAMS(decr($1), $2)M4_COMMA_IF(decr($1))`$2'decr($1)', `')')dnl
diff --git a/3rdparty/mockitopp/detail/m4/ENUM_SHIFTED_PARAMS.m4 b/3rdparty/mockitopp/detail/m4/ENUM_SHIFTED_PARAMS.m4
new file mode 100644
index 0000000..661a144
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/ENUM_SHIFTED_PARAMS.m4
@@ -0,0 +1,2 @@
+include(`mockitopp/detail/m4/COMMA_IF.m4')dnl
+define(`M4_ENUM_SHIFTED_PARAMS', `ifelse(eval($1 > 1), 1, `M4_ENUM_SHIFTED_PARAMS(decr($1), $2)M4_COMMA_IF(decr($1)-1)`$2'decr($1)', `')')dnl
diff --git a/3rdparty/mockitopp/detail/m4/ENUM_TRAILING_PARAMS.m4 b/3rdparty/mockitopp/detail/m4/ENUM_TRAILING_PARAMS.m4
new file mode 100644
index 0000000..e36bb0b
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/ENUM_TRAILING_PARAMS.m4
@@ -0,0 +1 @@
+define(`M4_ENUM_TRAILING_PARAMS', `ifelse(eval($1 > 0), 1, `M4_ENUM_TRAILING_PARAMS(decr($1), $2), `$2'decr($1)', `')')dnl
diff --git a/3rdparty/mockitopp/detail/m4/IF.m4 b/3rdparty/mockitopp/detail/m4/IF.m4
new file mode 100644
index 0000000..a5e716a
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/IF.m4
@@ -0,0 +1 @@
+define(`M4_IF', `ifelse(eval($1 > 0), 1, `$2', `$3')')dnl
diff --git a/3rdparty/mockitopp/detail/m4/REPEAT.m4 b/3rdparty/mockitopp/detail/m4/REPEAT.m4
new file mode 100644
index 0000000..39a3182
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/REPEAT.m4
@@ -0,0 +1 @@
+define(`M4_REPEAT', `ifelse(eval($1 > 0), 1,`M4_REPEAT(decr($1), `$2') $2(decr($1))', `')')dnl
diff --git a/3rdparty/mockitopp/detail/m4/REPEAT_FROM_TO.m4 b/3rdparty/mockitopp/detail/m4/REPEAT_FROM_TO.m4
new file mode 100644
index 0000000..76e0bc8
--- /dev/null
+++ b/3rdparty/mockitopp/detail/m4/REPEAT_FROM_TO.m4
@@ -0,0 +1 @@
+define(`M4_REPEAT_FROM_TO', `ifelse(eval($2 > $1), 1,`M4_REPEAT_FROM_TO($1, decr($2), `$3') $3(decr($2))', `')')dnl
diff --git a/3rdparty/mockitopp/detail/stubbing/action.hpp b/3rdparty/mockitopp/detail/stubbing/action.hpp
new file mode 100644
index 0000000..c8d0a3f
--- /dev/null
+++ b/3rdparty/mockitopp/detail/stubbing/action.hpp
@@ -0,0 +1,48 @@
+#ifndef __MOCKITOPP_ACTION_HPP__
+#define __MOCKITOPP_ACTION_HPP__
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ template <typename R>
+ struct action
+ {
+ virtual R invoke() = 0;
+
+ virtual ~action() {}
+ };
+
+ template <typename R>
+ struct returnable_action : public action<R>
+ {
+ R _returnable;
+
+ returnable_action(const R& returnable)
+ : _returnable(returnable)
+ {}
+
+ R invoke() { return _returnable; }
+ };
+
+ template <>
+ struct returnable_action<void> : public action<void>
+ {
+ void invoke() {}
+ };
+
+ template <typename R, typename T>
+ struct throwable_action : public action<R>
+ {
+ T _throwable;
+
+ throwable_action(const T& throwable)
+ : _throwable(throwable)
+ {}
+
+ R invoke() { throw _throwable; }
+ };
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_ACTION_HPP__
diff --git a/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp b/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp
new file mode 100644
index 0000000..8bd3fb7
--- /dev/null
+++ b/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp
@@ -0,0 +1,139 @@
+#ifndef __MOCKITOPP_DYNAMIC_OBJECT_HPP__
+#define __MOCKITOPP_DYNAMIC_OBJECT_HPP__
+
+#include <mockitopp/exceptions.hpp>
+#include <mockitopp/detail/stubbing/dynamic_vfunction.hpp>
+#include <mockitopp/detail/stubbing/proxy_vfunction.hpp>
+#include <mockitopp/detail/util/remove_member_function_pointer_cv.hpp>
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * helper class to find the vtable offset given a member function pointer
+ */
+ struct vtable_offset_helper
+ {
+ template <typename T>
+ static int get(T ptr2member)
+ {
+ vtable_offset_helper f;
+ return (f.*reinterpret_cast<int (vtable_offset_helper::*)()>(ptr2member))();
+ }
+
+ virtual int offset0() { return 0; }
+ virtual int offset1() { return 1; }
+ virtual int offset2() { return 2; }
+ virtual int offset3() { return 3; }
+ virtual int offset4() { return 4; }
+ virtual int offset5() { return 5; }
+ virtual int offset6() { return 6; }
+ virtual int offset7() { return 7; }
+ virtual int offset8() { return 8; }
+ virtual int offset9() { return 9; }
+ virtual int offset10() { return 10; }
+ virtual int offset11() { return 11; }
+ virtual int offset12() { return 12; }
+ virtual int offset13() { return 13; }
+ virtual int offset14() { return 14; }
+ virtual int offset15() { return 15; }
+ virtual int offset16() { return 16; }
+ virtual int offset17() { return 17; }
+ virtual int offset18() { return 18; }
+ virtual int offset19() { return 19; }
+ virtual int offset20() { return 20; }
+ virtual int offset21() { return 21; }
+ virtual int offset22() { return 22; }
+ virtual int offset23() { return 23; }
+ virtual int offset24() { return 24; }
+ virtual int offset25() { return 25; }
+ virtual int offset26() { return 26; }
+ virtual int offset27() { return 27; }
+ virtual int offset28() { return 28; }
+ virtual int offset29() { return 29; }
+ virtual int offset30() { return 30; }
+ virtual int offset31() { return 31; }
+ virtual int offset32() { return 32; }
+ virtual int offset33() { return 33; }
+ virtual int offset34() { return 34; }
+ virtual int offset35() { return 35; }
+ virtual int offset36() { return 36; }
+ virtual int offset37() { return 37; }
+ virtual int offset38() { return 38; }
+ virtual int offset39() { return 39; }
+ virtual int offset40() { return 40; }
+ virtual int offset41() { return 41; }
+ virtual int offset42() { return 42; }
+ virtual int offset43() { return 43; }
+ virtual int offset44() { return 44; }
+ virtual int offset45() { return 45; }
+ virtual int offset46() { return 46; }
+ virtual int offset47() { return 47; }
+ virtual int offset48() { return 48; }
+ virtual int offset49() { return 49; }
+
+ virtual ~vtable_offset_helper() {}
+ };
+
+ /**
+ * implementation class for pseduo-dynamically defining an interface
+ */
+ struct dynamic_object
+ {
+ struct vtable {
+ void* vbase_offset;
+ void* vcall_offset;
+ void* offset_to_top;
+ void* type_info;
+ void* functions[50];
+ };
+
+ void* vtable_object_ptr;
+ void* vtable_mocks[50];
+ vtable* vtable_actual_ptr;
+
+ dynamic_object()
+ : vtable_actual_ptr(new vtable)
+ {
+ vtable_actual_ptr->vbase_offset = 0;
+ vtable_actual_ptr->vcall_offset = 0;
+ vtable_actual_ptr->offset_to_top = 0;
+ vtable_actual_ptr->type_info = 0;
+ for(int i = 0; i < 50; i++)
+ {
+ vtable_actual_ptr->functions[i] = horrible_cast<void*>(&dynamic_object::missing_vfunction);
+ vtable_mocks[i] = 0;
+ }
+ vtable_object_ptr = vtable_actual_ptr->functions;
+ }
+
+ ~dynamic_object()
+ {
+ for(int i = 0; i < 50; i++)
+ {
+ if(vtable_mocks[i] != 0)
+ { delete reinterpret_cast<dynamic_vfunction_base*>(vtable_mocks[i]); }
+ }
+ delete vtable_actual_ptr;
+ }
+
+ template <typename M>
+ dynamic_vfunction<typename remove_member_function_pointer_cv<M>::type>& define_function(M ptr2member)
+ {
+ int offset = vtable_offset_helper::get(ptr2member);
+ if(vtable_mocks[offset] == 0)
+ {
+ vtable_actual_ptr->functions[offset] = proxy_vfunction_factory<M>::get(ptr2member);
+ vtable_mocks[offset] = new dynamic_vfunction<typename remove_member_function_pointer_cv<M>::type>();
+ }
+ return *reinterpret_cast<dynamic_vfunction<typename remove_member_function_pointer_cv<M>::type>*>(vtable_mocks[offset]);
+ }
+
+ void missing_vfunction()
+ { throw missing_implementation_exception(); }
+ };
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_DYNAMIC_OBJECT_HPP__
diff --git a/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp.m4 b/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp.m4
new file mode 100644
index 0000000..9b62eb3
--- /dev/null
+++ b/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp.m4
@@ -0,0 +1,93 @@
+#ifndef __MOCKITOPP_DYNAMIC_OBJECT_HPP__
+#define __MOCKITOPP_DYNAMIC_OBJECT_HPP__
+
+#include <mockitopp/exceptions.hpp>
+#include <mockitopp/detail/stubbing/dynamic_vfunction.hpp>
+#include <mockitopp/detail/stubbing/proxy_vfunction.hpp>
+#include <mockitopp/detail/util/remove_member_function_pointer_cv.hpp>
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * helper class to find the vtable offset given a member function pointer
+ */
+ struct vtable_offset_helper
+ {
+ template <typename T>
+ static int get(T ptr2member)
+ {
+ vtable_offset_helper f;
+ return (f.*reinterpret_cast<int (vtable_offset_helper::*)()>(ptr2member))();
+ }
+
+include(`mockitopp/detail/m4/REPEAT.m4')dnl
+define(`DEFINE_VTABLE_OFFSET_HELPER_FUNCTION', ` virtual int offset$1() { return $1; }
+')dnl
+M4_REPEAT(MOCKITOPP_MAX_VIRTUAL_FUNCTIONS, `DEFINE_VTABLE_OFFSET_HELPER_FUNCTION')dnl
+
+ virtual ~vtable_offset_helper() {}
+ };
+
+ /**
+ * implementation class for pseduo-dynamically defining an interface
+ */
+ struct dynamic_object
+ {
+ struct vtable {
+ void* vbase_offset;
+ void* vcall_offset;
+ void* offset_to_top;
+ void* type_info;
+ void* functions[MOCKITOPP_MAX_VIRTUAL_FUNCTIONS];
+ };
+
+ void* vtable_object_ptr;
+ void* vtable_mocks[MOCKITOPP_MAX_VIRTUAL_FUNCTIONS];
+ vtable* vtable_actual_ptr;
+
+ dynamic_object()
+ : vtable_actual_ptr(new vtable)
+ {
+ vtable_actual_ptr->vbase_offset = 0;
+ vtable_actual_ptr->vcall_offset = 0;
+ vtable_actual_ptr->offset_to_top = 0;
+ vtable_actual_ptr->type_info = 0;
+ for(int i = 0; i < MOCKITOPP_MAX_VIRTUAL_FUNCTIONS; i++)
+ {
+ vtable_actual_ptr->functions[i] = horrible_cast<void*>(&dynamic_object::missing_vfunction);
+ vtable_mocks[i] = 0;
+ }
+ vtable_object_ptr = vtable_actual_ptr->functions;
+ }
+
+ ~dynamic_object()
+ {
+ for(int i = 0; i < MOCKITOPP_MAX_VIRTUAL_FUNCTIONS; i++)
+ {
+ if(vtable_mocks[i] != 0)
+ { delete reinterpret_cast<dynamic_vfunction_base*>(vtable_mocks[i]); }
+ }
+ delete vtable_actual_ptr;
+ }
+
+ template <typename M>
+ dynamic_vfunction<typename remove_member_function_pointer_cv<M>::type>& define_function(M ptr2member)
+ {
+ int offset = vtable_offset_helper::get(ptr2member);
+ if(vtable_mocks[offset] == 0)
+ {
+ vtable_actual_ptr->functions[offset] = proxy_vfunction_factory<M>::get(ptr2member);
+ vtable_mocks[offset] = new dynamic_vfunction<typename remove_member_function_pointer_cv<M>::type>();
+ }
+ return *reinterpret_cast<dynamic_vfunction<typename remove_member_function_pointer_cv<M>::type>*>(vtable_mocks[offset]);
+ }
+
+ void missing_vfunction()
+ { throw missing_implementation_exception(); }
+ };
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_DYNAMIC_OBJECT_HPP__
diff --git a/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp b/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp
new file mode 100644
index 0000000..92a425d
--- /dev/null
+++ b/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp
@@ -0,0 +1,1194 @@
+#ifndef __MOCKITOPP_DYNAMIC_VFUNCTION_HPP__
+#define __MOCKITOPP_DYNAMIC_VFUNCTION_HPP__
+
+#include <algorithm>
+#include <list>
+
+#include <mockitopp/exceptions.hpp>
+#include <mockitopp/detail/stubbing/action.hpp>
+#include <mockitopp/detail/util/pointers.hpp>
+#include <mockitopp/detail/util/tr1_tuple.hpp>
+#include <mockitopp/matchers/Matcher.hpp>
+
+// TODO: add documentation
+namespace mockitopp
+{
+ namespace detail
+ {
+ struct dynamic_vfunction_base
+ {
+ int calls;
+
+ // allow polymorphic desctruction with unknown subtype
+ virtual ~dynamic_vfunction_base() {}
+
+ /**
+ * verify method is called within a specified range
+ *
+ * @param min minimum times method should be called
+ * @param max maximum times method should be called
+ */
+ bool between(int min, int max) const
+ {
+ if(calls >= min && calls <= max)
+ { return true; }
+ return false;
+ }
+
+ /**
+ * verify method is called at least (n) times
+ *
+ * @param times minimum number of times method should be called
+ */
+ bool atLeast(int times) const
+ { return calls >= times; }
+
+ /**
+ * verify method is called at most (n) times
+ *
+ * @param times maximum number of times method should be called
+ */
+ bool atMost(int times) const
+ { return calls <= times; }
+
+ /**
+ * verify method is called exactly (n) times
+ *
+ * @param times exact number of times method should be called
+ */
+ bool exactly(int times) const
+ { return calls == times; }
+
+ /**
+ * verify method is never called
+ */
+ bool never() const
+ { return calls == 0; }
+ };
+
+ template <typename R>
+ struct dynamic_vfunction_progress : dynamic_vfunction_base
+ {
+ typedef shared_ptr<action<R> > action_type;
+ typedef std::list<action_type> action_queue_type;
+
+ action_queue_type* stubbing_progress;
+
+ dynamic_vfunction_progress& thenReturn(R value)
+ {
+ stubbing_progress->push_back(action_type(new returnable_action<R>(value)));
+ return *this;
+ }
+
+ template <typename T>
+ dynamic_vfunction_progress& thenThrow(T throwable)
+ {
+ stubbing_progress->push_back(action_type(new throwable_action<R, T>(throwable)));
+ return *this;
+ }
+ };
+
+ template <>
+ struct dynamic_vfunction_progress<void> : dynamic_vfunction_base
+ {
+ typedef shared_ptr<action<void> > action_type;
+ typedef std::list<action_type> action_queue_type;
+
+ action_queue_type* stubbing_progress;
+
+ dynamic_vfunction_progress& thenReturn()
+ {
+ stubbing_progress->push_back(action_type(new returnable_action<void>()));
+ return *this;
+ }
+
+ template <typename T>
+ dynamic_vfunction_progress& thenThrow(T throwable)
+ {
+ stubbing_progress->push_back(action_type(new throwable_action<void, T>(throwable)));
+ return *this;
+ }
+ };
+
+ template <typename K, typename V>
+ struct map_entry
+ {
+ K key;
+ V val;
+
+ map_entry(const K& k, const V& v) : key(k), val(v) {}
+
+ template <typename K2, typename V2>
+ bool operator== (const map_entry<K2, V2>& rhs) const
+ { return key == rhs.key; }
+
+ template <typename T>
+ bool operator== (const T& rhs) const
+ { return key == rhs; }
+ };
+
+ template <typename T>
+ struct matcher_element
+ {
+ matcher::Matcher<T>* matcher;
+
+ matcher_element(const matcher::Matcher<T>& _matcher)
+ : matcher(_matcher.clone())
+ {}
+
+ matcher_element(const matcher_element& rhs)
+ : matcher(rhs.matcher->clone())
+ {}
+
+ ~matcher_element()
+ { delete matcher; }
+
+ bool operator== (typename tr1::add_reference<typename tr1::add_const<T>::type>::type rhs) const
+ { return (*matcher == rhs); }
+
+ bool operator== (const matcher_element& rhs) const
+ { return (matcher == rhs.matcher); }
+ };
+
+ template <typename T> struct dynamic_vfunction;
+
+ // TODO: clean up impl
+ // TODO: add sequence matcher
+
+ // TODO: clean up typedef nomenclature
+
+ // 0 arity template
+ template <typename R, typename C>
+ struct dynamic_vfunction<R (C::*)()> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<> exact_tuple_type;
+ typedef tr1::tuple< > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+
+
+ dynamic_vfunction_progress<R>& when()
+ {
+ const exact_tuple_type args = exact_tuple_type();
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke()
+ {
+ const exact_tuple_type args = exact_tuple_type();
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 1 arity template
+ template <typename R, typename C, typename A0>
+ struct dynamic_vfunction<R (C::*)(A0)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 2 arity template
+ template <typename R, typename C, typename A0, typename A1>
+ struct dynamic_vfunction<R (C::*)(A0, A1)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 3 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 4 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2, A3)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2, A3> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 >, matcher_element<A3 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2, const matcher::Matcher<A3 >& a3)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 5 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2, A3, A4> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 >, matcher_element<A3 >, matcher_element<A4 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2, const matcher::Matcher<A3 >& a3, const matcher::Matcher<A4 >& a4)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 6 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2, A3, A4, A5> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 >, matcher_element<A3 >, matcher_element<A4 >, matcher_element<A5 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2, const matcher::Matcher<A3 >& a3, const matcher::Matcher<A4 >& a4, const matcher::Matcher<A5 >& a5)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 7 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2, A3, A4, A5, A6> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 >, matcher_element<A3 >, matcher_element<A4 >, matcher_element<A5 >, matcher_element<A6 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2, const matcher::Matcher<A3 >& a3, const matcher::Matcher<A4 >& a4, const matcher::Matcher<A5 >& a5, const matcher::Matcher<A6 >& a6)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 8 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2, A3, A4, A5, A6, A7> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 >, matcher_element<A3 >, matcher_element<A4 >, matcher_element<A5 >, matcher_element<A6 >, matcher_element<A7 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2, const matcher::Matcher<A3 >& a3, const matcher::Matcher<A4 >& a4, const matcher::Matcher<A5 >& a5, const matcher::Matcher<A6 >& a6, const matcher::Matcher<A7 >& a7)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 9 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 >, matcher_element<A3 >, matcher_element<A4 >, matcher_element<A5 >, matcher_element<A6 >, matcher_element<A7 >, matcher_element<A8 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2, const matcher::Matcher<A3 >& a3, const matcher::Matcher<A4 >& a4, const matcher::Matcher<A5 >& a5, const matcher::Matcher<A6 >& a6, const matcher::Matcher<A7 >& a7, const matcher::Matcher<A8 >& a8)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+
+ // 10 arity template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ struct dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9> exact_tuple_type;
+ typedef tr1::tuple<matcher_element<A0 >, matcher_element<A1 >, matcher_element<A2 >, matcher_element<A3 >, matcher_element<A4 >, matcher_element<A5 >, matcher_element<A6 >, matcher_element<A7 >, matcher_element<A8 >, matcher_element<A9 > > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ dynamic_vfunction_progress<R>& when(const matcher::Matcher<A0 >& a0, const matcher::Matcher<A1 >& a1, const matcher::Matcher<A2 >& a2, const matcher::Matcher<A3 >& a3, const matcher::Matcher<A4 >& a4, const matcher::Matcher<A5 >& a5, const matcher::Matcher<A6 >& a6, const matcher::Matcher<A7 >& a7, const matcher::Matcher<A8 >& a8, const matcher::Matcher<A9 >& a9)
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ dynamic_vfunction_progress<R>& when(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+ {
+ const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_DYNAMIC_VFUNCTION_HPP__
diff --git a/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp.m4 b/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp.m4
new file mode 100644
index 0000000..6a1fa6a
--- /dev/null
+++ b/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp.m4
@@ -0,0 +1,265 @@
+#ifndef __MOCKITOPP_DYNAMIC_VFUNCTION_HPP__
+#define __MOCKITOPP_DYNAMIC_VFUNCTION_HPP__
+
+#include <algorithm>
+#include <list>
+
+#include <mockitopp/exceptions.hpp>
+#include <mockitopp/detail/stubbing/action.hpp>
+#include <mockitopp/detail/util/pointers.hpp>
+#include <mockitopp/detail/util/tr1_tuple.hpp>
+#include <mockitopp/matchers/Matcher.hpp>
+
+include(`mockitopp/detail/m4/ENUM_BINARY_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/ENUM_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/ENUM_TRAILING_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/IF.m4')dnl
+include(`mockitopp/detail/m4/REPEAT.m4')dnl
+// TODO: add documentation
+namespace mockitopp
+{
+ namespace detail
+ {
+ struct dynamic_vfunction_base
+ {
+ int calls;
+
+ // allow polymorphic desctruction with unknown subtype
+ virtual ~dynamic_vfunction_base() {}
+
+ /**
+ * verify method is called within a specified range
+ *
+ * @param min minimum times method should be called
+ * @param max maximum times method should be called
+ */
+ bool between(int min, int max) const
+ {
+ if(calls >= min && calls <= max)
+ { return true; }
+ return false;
+ }
+
+ /**
+ * verify method is called at least (n) times
+ *
+ * @param times minimum number of times method should be called
+ */
+ bool atLeast(int times) const
+ { return calls >= times; }
+
+ /**
+ * verify method is called at most (n) times
+ *
+ * @param times maximum number of times method should be called
+ */
+ bool atMost(int times) const
+ { return calls <= times; }
+
+ /**
+ * verify method is called exactly (n) times
+ *
+ * @param times exact number of times method should be called
+ */
+ bool exactly(int times) const
+ { return calls == times; }
+
+ /**
+ * verify method is never called
+ */
+ bool never() const
+ { return calls == 0; }
+ };
+
+ template <typename R>
+ struct dynamic_vfunction_progress : dynamic_vfunction_base
+ {
+ typedef shared_ptr<action<R> > action_type;
+ typedef std::list<action_type> action_queue_type;
+
+ action_queue_type* stubbing_progress;
+
+ dynamic_vfunction_progress& thenReturn(R value)
+ {
+ stubbing_progress->push_back(action_type(new returnable_action<R>(value)));
+ return *this;
+ }
+
+ template <typename T>
+ dynamic_vfunction_progress& thenThrow(T throwable)
+ {
+ stubbing_progress->push_back(action_type(new throwable_action<R, T>(throwable)));
+ return *this;
+ }
+ };
+
+ template <>
+ struct dynamic_vfunction_progress<void> : dynamic_vfunction_base
+ {
+ typedef shared_ptr<action<void> > action_type;
+ typedef std::list<action_type> action_queue_type;
+
+ action_queue_type* stubbing_progress;
+
+ dynamic_vfunction_progress& thenReturn()
+ {
+ stubbing_progress->push_back(action_type(new returnable_action<void>()));
+ return *this;
+ }
+
+ template <typename T>
+ dynamic_vfunction_progress& thenThrow(T throwable)
+ {
+ stubbing_progress->push_back(action_type(new throwable_action<void, T>(throwable)));
+ return *this;
+ }
+ };
+
+ template <typename K, typename V>
+ struct map_entry
+ {
+ K key;
+ V val;
+
+ map_entry(const K& k, const V& v) : key(k), val(v) {}
+
+ template <typename K2, typename V2>
+ bool operator== (const map_entry<K2, V2>& rhs) const
+ { return key == rhs.key; }
+
+ template <typename T>
+ bool operator== (const T& rhs) const
+ { return key == rhs; }
+ };
+
+ template <typename T>
+ struct matcher_element
+ {
+ matcher::Matcher<T>* matcher;
+
+ matcher_element(const matcher::Matcher<T>& _matcher)
+ : matcher(_matcher.clone())
+ {}
+
+ matcher_element(const matcher_element& rhs)
+ : matcher(rhs.matcher->clone())
+ {}
+
+ ~matcher_element()
+ { delete matcher; }
+
+ bool operator== (typename tr1::add_reference<typename tr1::add_const<T>::type>::type rhs) const
+ { return (*matcher == rhs); }
+
+ bool operator== (const matcher_element& rhs) const
+ { return (matcher == rhs.matcher); }
+ };
+
+ template <typename T> struct dynamic_vfunction;
+
+ // TODO: clean up impl
+ // TODO: add sequence matcher
+
+ // TODO: clean up typedef nomenclature
+define(`DEFINE_DYNAMIC_VFUNCTION', `
+ // $1 arity template
+ template <typename R, typename C`'M4_ENUM_TRAILING_PARAMS($1, typename A)>
+ struct dynamic_vfunction<R (C::*)(M4_ENUM_PARAMS($1, A))> : private dynamic_vfunction_progress<R>
+ {
+ typedef tr1::tuple<M4_ENUM_PARAMS($1, A)> exact_tuple_type;
+ typedef tr1::tuple<M4_ENUM_BINARY_PARAMS($1, matcher_element<A, >, M4_INTERCEPT) > fuzzy_tuple_type;
+
+ typedef typename dynamic_vfunction_progress<R>::action_type action_type;
+ typedef typename dynamic_vfunction_progress<R>::action_queue_type action_queue_type;
+
+ std::list<map_entry<exact_tuple_type, action_queue_type> > exact_matches;
+ std::list<map_entry<fuzzy_tuple_type, action_queue_type> > fuzzy_matches;
+ std::list<map_entry<exact_tuple_type, int> > args_to_calls;
+
+ dynamic_vfunction()
+ : dynamic_vfunction_progress<R>()
+ , exact_matches()
+ , fuzzy_matches()
+ {}
+
+ template <typename T>
+ int calculate_calls_for_arguments(const T args) {
+ int calls = 0;
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = args_to_calls.begin();
+ for(; calls_it != args_to_calls.end(); calls_it++) {
+ if(args == calls_it->key) {
+ calls += calls_it->val;
+ }
+ }
+ return calls;
+ }
+
+ M4_IF($1, `dynamic_vfunction_progress<R>& when(M4_ENUM_BINARY_PARAMS($1, const matcher::Matcher<A, >& a))
+ {
+ const fuzzy_tuple_type args = fuzzy_tuple_type(M4_ENUM_PARAMS($1, a));
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(match == fuzzy_matches.end())
+ {
+ fuzzy_matches.push_back(map_entry<fuzzy_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --fuzzy_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }',)
+
+ dynamic_vfunction_progress<R>& when(M4_ENUM_BINARY_PARAMS($1, A, a))
+ {
+ const exact_tuple_type args = exact_tuple_type(M4_ENUM_PARAMS($1, a));
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(match == exact_matches.end())
+ {
+ exact_matches.push_back(map_entry<exact_tuple_type, action_queue_type>(args, action_queue_type()));
+ match = --exact_matches.end();
+ }
+ this->calls = calculate_calls_for_arguments(args);
+ this->stubbing_progress = &(match->val);
+ return *this;
+ }
+
+ R invoke(M4_ENUM_BINARY_PARAMS($1, A, a))
+ {
+ const exact_tuple_type args = exact_tuple_type(M4_ENUM_PARAMS($1, a));
+
+ typename std::list<map_entry<exact_tuple_type, int> >::iterator calls_it
+ = std::find(args_to_calls.begin(), args_to_calls.end(), args);
+ if(calls_it == args_to_calls.end()) {
+ args_to_calls.push_back(map_entry<exact_tuple_type, int>(args, 1));
+ } else {
+ (calls_it->val)++;
+ }
+
+ action_queue_type* actions = 0;
+ typename std::list<map_entry<exact_tuple_type, action_queue_type> >::iterator exact_match
+ = std::find(exact_matches.begin(), exact_matches.end(), args);
+ if(exact_match != exact_matches.end())
+ { actions = &(exact_match->val); }
+ if(!actions)
+ {
+ typename std::list<map_entry<fuzzy_tuple_type, action_queue_type> >::iterator fuzzy_match
+ = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args);
+ if(fuzzy_match == fuzzy_matches.end())
+ { throw partial_implementation_exception(); }
+ actions = &(fuzzy_match->val);
+ }
+ action_type action = actions->front();
+ if(actions->size() > 1)
+ { actions->pop_front(); }
+ return action->invoke();
+ }
+ };
+')dnl
+dnl add one to max arity so we generate 0 argument case
+M4_REPEAT(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY + 1), `DEFINE_DYNAMIC_VFUNCTION')dnl
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_DYNAMIC_VFUNCTION_HPP__
diff --git a/3rdparty/mockitopp/detail/stubbing/proxy_vfunction.hpp b/3rdparty/mockitopp/detail/stubbing/proxy_vfunction.hpp
new file mode 100644
index 0000000..ca9539a
--- /dev/null
+++ b/3rdparty/mockitopp/detail/stubbing/proxy_vfunction.hpp
@@ -0,0 +1,201 @@
+#ifndef __MOCKITOPP_PROXY_VFUNCTION_HPP__
+#define __MOCKITOPP_PROXY_VFUNCTION_HPP__
+
+#include <mockitopp/detail/stubbing/dynamic_vfunction.hpp>
+#include <mockitopp/detail/util/horrible_cast.hpp>
+#include <mockitopp/detail/util/remove_member_function_pointer_cv.hpp>
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ template <int OFFSET, typename T> struct proxy_vfunction;
+
+ template <int OFFSET, typename R, typename C >
+ struct proxy_vfunction<OFFSET, R (C::*)()>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)()>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke()
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2, A3)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6, a7); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ };
+
+ template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)>*
+ __PAD_FOR_MOCK_spys[50];
+
+ R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ };
+
+
+ template <typename M>
+ struct proxy_vfunction_factory
+ {
+ static void* get(M ptr2member)
+ {
+ proxy_vfunction_factory s;
+ return (s.*reinterpret_cast<void* (proxy_vfunction_factory::*)()>(ptr2member))();
+ }
+
+ virtual void* offset0() { return horrible_cast<void*>(&proxy_vfunction<0, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset1() { return horrible_cast<void*>(&proxy_vfunction<1, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset2() { return horrible_cast<void*>(&proxy_vfunction<2, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset3() { return horrible_cast<void*>(&proxy_vfunction<3, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset4() { return horrible_cast<void*>(&proxy_vfunction<4, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset5() { return horrible_cast<void*>(&proxy_vfunction<5, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset6() { return horrible_cast<void*>(&proxy_vfunction<6, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset7() { return horrible_cast<void*>(&proxy_vfunction<7, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset8() { return horrible_cast<void*>(&proxy_vfunction<8, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset9() { return horrible_cast<void*>(&proxy_vfunction<9, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset10() { return horrible_cast<void*>(&proxy_vfunction<10, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset11() { return horrible_cast<void*>(&proxy_vfunction<11, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset12() { return horrible_cast<void*>(&proxy_vfunction<12, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset13() { return horrible_cast<void*>(&proxy_vfunction<13, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset14() { return horrible_cast<void*>(&proxy_vfunction<14, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset15() { return horrible_cast<void*>(&proxy_vfunction<15, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset16() { return horrible_cast<void*>(&proxy_vfunction<16, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset17() { return horrible_cast<void*>(&proxy_vfunction<17, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset18() { return horrible_cast<void*>(&proxy_vfunction<18, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset19() { return horrible_cast<void*>(&proxy_vfunction<19, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset20() { return horrible_cast<void*>(&proxy_vfunction<20, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset21() { return horrible_cast<void*>(&proxy_vfunction<21, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset22() { return horrible_cast<void*>(&proxy_vfunction<22, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset23() { return horrible_cast<void*>(&proxy_vfunction<23, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset24() { return horrible_cast<void*>(&proxy_vfunction<24, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset25() { return horrible_cast<void*>(&proxy_vfunction<25, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset26() { return horrible_cast<void*>(&proxy_vfunction<26, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset27() { return horrible_cast<void*>(&proxy_vfunction<27, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset28() { return horrible_cast<void*>(&proxy_vfunction<28, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset29() { return horrible_cast<void*>(&proxy_vfunction<29, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset30() { return horrible_cast<void*>(&proxy_vfunction<30, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset31() { return horrible_cast<void*>(&proxy_vfunction<31, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset32() { return horrible_cast<void*>(&proxy_vfunction<32, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset33() { return horrible_cast<void*>(&proxy_vfunction<33, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset34() { return horrible_cast<void*>(&proxy_vfunction<34, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset35() { return horrible_cast<void*>(&proxy_vfunction<35, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset36() { return horrible_cast<void*>(&proxy_vfunction<36, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset37() { return horrible_cast<void*>(&proxy_vfunction<37, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset38() { return horrible_cast<void*>(&proxy_vfunction<38, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset39() { return horrible_cast<void*>(&proxy_vfunction<39, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset40() { return horrible_cast<void*>(&proxy_vfunction<40, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset41() { return horrible_cast<void*>(&proxy_vfunction<41, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset42() { return horrible_cast<void*>(&proxy_vfunction<42, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset43() { return horrible_cast<void*>(&proxy_vfunction<43, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset44() { return horrible_cast<void*>(&proxy_vfunction<44, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset45() { return horrible_cast<void*>(&proxy_vfunction<45, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset46() { return horrible_cast<void*>(&proxy_vfunction<46, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset47() { return horrible_cast<void*>(&proxy_vfunction<47, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset48() { return horrible_cast<void*>(&proxy_vfunction<48, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+ virtual void* offset49() { return horrible_cast<void*>(&proxy_vfunction<49, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+
+ virtual ~proxy_vfunction_factory() {}
+ };
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_PROXY_VFUNCTION_HPP__
diff --git a/3rdparty/mockitopp/detail/stubbing/proxy_vfunction.hpp.m4 b/3rdparty/mockitopp/detail/stubbing/proxy_vfunction.hpp.m4
new file mode 100644
index 0000000..20f7d29
--- /dev/null
+++ b/3rdparty/mockitopp/detail/stubbing/proxy_vfunction.hpp.m4
@@ -0,0 +1,52 @@
+#ifndef __MOCKITOPP_PROXY_VFUNCTION_HPP__
+#define __MOCKITOPP_PROXY_VFUNCTION_HPP__
+
+#include <mockitopp/detail/stubbing/dynamic_vfunction.hpp>
+#include <mockitopp/detail/util/horrible_cast.hpp>
+#include <mockitopp/detail/util/remove_member_function_pointer_cv.hpp>
+
+include(`mockitopp/detail/m4/ENUM_BINARY_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/ENUM_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/ENUM_TRAILING_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/REPEAT.m4')dnl
+namespace mockitopp
+{
+ namespace detail
+ {
+ template <int OFFSET, typename T> struct proxy_vfunction;
+
+define(`DEFINE_PROXY_VFUNCTION',
+` template <int OFFSET, typename R, typename C M4_ENUM_TRAILING_PARAMS($1, typename A)>
+ struct proxy_vfunction<OFFSET, R (C::*)(M4_ENUM_PARAMS($1, A))>
+ {
+ void* __PAD_FOR_MOCK_vptr;
+ dynamic_vfunction<R (C::*)(M4_ENUM_PARAMS($1, A))>*
+ __PAD_FOR_MOCK_spys[MOCKITOPP_MAX_VIRTUAL_FUNCTIONS];
+
+ R invoke(M4_ENUM_BINARY_PARAMS($1, A, a))
+ { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(M4_ENUM_PARAMS($1, a)); }
+ };
+
+')dnl
+dnl add one to max arity so we generate 0 argument case
+M4_REPEAT(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY + 1), `DEFINE_PROXY_VFUNCTION')dnl
+
+ template <typename M>
+ struct proxy_vfunction_factory
+ {
+ static void* get(M ptr2member)
+ {
+ proxy_vfunction_factory s;
+ return (s.*reinterpret_cast<void* (proxy_vfunction_factory::*)()>(ptr2member))();
+ }
+
+define(`DEFINE_PROXY_VFUNCTION_FACTORY_OFFSET_FUNCTION', ` virtual void* offset$1() { return horrible_cast<void*>(&proxy_vfunction<$1, typename remove_member_function_pointer_cv<M>::type>::invoke); }
+')dnl
+M4_REPEAT(MOCKITOPP_MAX_VIRTUAL_FUNCTIONS, `DEFINE_PROXY_VFUNCTION_FACTORY_OFFSET_FUNCTION')dnl
+
+ virtual ~proxy_vfunction_factory() {}
+ };
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_PROXY_VFUNCTION_HPP__
diff --git a/3rdparty/mockitopp/detail/util/cxx0x_static_assert.hpp b/3rdparty/mockitopp/detail/util/cxx0x_static_assert.hpp
new file mode 100644
index 0000000..9821f30
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/cxx0x_static_assert.hpp
@@ -0,0 +1,22 @@
+#ifndef __MOCKITOPP_CXX0X_STATIC_ASSERT_HPP__
+#define __MOCKITOPP_CXX0X_STATIC_ASSERT_HPP__
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * An emulation of the C++0x static_assert macro that can be
+ * used to force a compile time error in older compilers.
+ *
+ * @author Trevor Pounds
+ */
+ template <bool E> struct static_assert_impl { typedef bool type; };
+ template <> struct static_assert_impl<false> { };
+
+ #define mockitopp_static_assert(constant_expression) \
+ typedef typename ::mockitopp::detail::static_assert_impl<constant_expression>::type MOCKITOPP_STATIC_ASSERT_TYPE;
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_CXX0X_STATIC_ASSERT_HPP__
diff --git a/3rdparty/mockitopp/detail/util/horrible_cast.hpp b/3rdparty/mockitopp/detail/util/horrible_cast.hpp
new file mode 100644
index 0000000..e89ad71
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/horrible_cast.hpp
@@ -0,0 +1,37 @@
+#ifndef __MOCKITOPP_HORRIBLE_CAST_HPP__
+#define __MOCKITOPP_HORRIBLE_CAST_HPP__
+
+#include <mockitopp/detail/util/cxx0x_static_assert.hpp>
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * A potentially unsafe cast using a union of two possibly
+ * incompatible data types that can be used to completely
+ * subvert the compiler's cast system...USE WITH CAUTION!
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T, typename F>
+ T horrible_cast(F from)
+ {
+ /**
+ * Abort compilation to avoid casting potentially
+ * incompatible types due obvious differences in size.
+ */
+ //mockitopp_static_assert(sizeof(T) == sizeof(F));
+
+ union
+ {
+ F from;
+ T to;
+ } u;
+ u.from = from;
+ return u.to;
+ }
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_HORRIBLE_CAST_HPP__
diff --git a/3rdparty/mockitopp/detail/util/pointers.hpp b/3rdparty/mockitopp/detail/util/pointers.hpp
new file mode 100644
index 0000000..85671ee
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/pointers.hpp
@@ -0,0 +1,225 @@
+#ifndef __MOCKITOPP_POINTERS_PTR__
+#define __MOCKITOPP_POINTERS_PTR__
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * The default deleter functor used by shared_ptr
+ * to free the underlying allocated memory.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T>
+ struct default_ptr_deleter
+ {
+ void operator() (T* ptr)
+ { delete ptr; }
+ };
+
+ /**
+ * A reference counting "smart" pointer similar to
+ * the ones provided by boost, tr1, c++0x, etc.
+ *
+ * NOTE:
+ *
+ * Concurrent usage is not supported since the
+ * reference counter is not modified atomically.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T, typename D = default_ptr_deleter<T> >
+ class shared_ptr
+ {
+ public:
+
+ shared_ptr()
+ : _ptr_impl()
+ {}
+
+ shared_ptr(const shared_ptr& rhs)
+ : _ptr_impl(rhs._ptr_impl)
+ { __increment(); }
+
+ explicit shared_ptr(T* raw_ptr)
+ : _ptr_impl(new shared_ptr_impl(raw_ptr, 1))
+ {}
+
+ ~shared_ptr() { __decrement(); }
+
+ bool operator==(const shared_ptr& rhs) const { return _ptr_impl == rhs._ptr_impl; }
+ bool operator!=(const shared_ptr& rhs) const { return _ptr_impl != rhs._ptr_impl; }
+ bool operator<(const shared_ptr& rhs) const { return _ptr_impl < rhs._ptr_impl; }
+ bool operator>(const shared_ptr& rhs) const { return _ptr_impl > rhs._ptr_impl; }
+ bool operator<=(const shared_ptr& rhs) const { return _ptr_impl <= rhs._ptr_impl; }
+ bool operator>=(const shared_ptr& rhs) const { return _ptr_impl >= rhs._ptr_impl; }
+
+ shared_ptr& operator=(const shared_ptr& rhs)
+ {
+ if(this != &rhs)
+ {
+ __decrement();
+ _ptr_impl = rhs._ptr_impl;
+ __increment();
+ }
+ return *this;
+ }
+
+ T* get() const { return (_ptr_impl) ? _ptr_impl->_raw_ptr : 0; }
+ T& operator*() const { return *get(); }
+ T* operator->() const { return get(); }
+
+ private:
+
+ struct shared_ptr_impl
+ {
+ T* _raw_ptr;
+ size_t _count;
+
+ shared_ptr_impl(T* raw_ptr = 0, size_t count = 0)
+ : _raw_ptr(raw_ptr)
+ , _count(count)
+ {}
+
+ ~shared_ptr_impl()
+ { D()(_raw_ptr); }
+ }* _ptr_impl;
+
+ void __decrement()
+ {
+ if(_ptr_impl && --(_ptr_impl->_count) == 0)
+ { delete _ptr_impl; }
+ }
+
+ void __increment()
+ {
+ if(_ptr_impl)
+ { (_ptr_impl->_count)++; }
+ }
+ };
+
+ /**
+ * The default deleter functor used by shared_array
+ * to free the underlying allocated memory.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T>
+ struct default_array_deleter
+ {
+ void operator() (T* array)
+ { delete[] array; }
+ };
+
+ /**
+ * A reference counting "smart" array pointer similar
+ * to the ones provided by boost, tr1, c++0x, etc.
+ *
+ * NOTE:
+ *
+ * Concurrent usage is not supported since the
+ * reference counter is not modified atomically.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T, typename D = default_array_deleter<T> >
+ class shared_array : public shared_ptr<T, D>
+ {
+ public:
+
+ shared_array()
+ : shared_ptr<T, D>()
+ {}
+
+ explicit shared_array(T* raw_ptr)
+ : shared_ptr<T, D>(raw_ptr)
+ {}
+
+ T& operator[] (size_t i) const { return *(shared_array::get() + i); }
+ };
+
+ /**
+ * A pointer that transfers ownership on copies and assignment.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T, typename D = default_ptr_deleter<T> >
+ class owned_ptr
+ {
+ public:
+
+ owned_ptr()
+ : _ptr(0)
+ {}
+
+ owned_ptr(const owned_ptr& rhs)
+ : _ptr((T*) ((size_t) rhs.release() | OWNER))
+ {}
+
+ explicit owned_ptr(T* ptr)
+ : _ptr((T*) ((size_t) ptr | OWNER))
+ {}
+
+ ~owned_ptr() { __delete(); }
+
+ owned_ptr& operator=(const owned_ptr& rhs)
+ {
+ if(this != &rhs)
+ {
+ if(get() != rhs.get())
+ { __delete(); }
+ _ptr = rhs._ptr;
+ rhs.release();
+ }
+ return *this;
+ }
+
+ bool is_owner() const { return ((size_t) _ptr & OWNER) == OWNER; }
+
+ T* get() const { return (T*) ((size_t) _ptr & POINTER); }
+ T& operator*() const { return *get(); }
+ T* operator->() const { return get(); }
+ T* release() const { return (_ptr = get()); }
+
+ private:
+
+ static const size_t OWNER = 0x1;
+ static const size_t POINTER = ~OWNER;
+
+ mutable T* _ptr;
+
+ void __delete()
+ {
+ if(is_owner())
+ {
+ D()(get());
+ _ptr = 0;
+ }
+ }
+ };
+
+ /**
+ * An array pointer that transfers ownership on copies and assignment.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T, typename D = default_array_deleter<T> >
+ class owned_array : public owned_ptr<T, D>
+ {
+ public:
+
+ owned_array()
+ : owned_ptr<T, D>()
+ {}
+
+ explicit owned_array(T* ptr)
+ : owned_ptr<T, D>(ptr)
+ {}
+
+ T& operator[] (size_t i) const { return *(owned_array::get() + i); }
+ };
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_POINTERS_PTR__
diff --git a/3rdparty/mockitopp/detail/util/remove_member_function_pointer_cv.hpp b/3rdparty/mockitopp/detail/util/remove_member_function_pointer_cv.hpp
new file mode 100644
index 0000000..8ec70bb
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/remove_member_function_pointer_cv.hpp
@@ -0,0 +1,132 @@
+#ifndef __MOCKITOPP_REMOVE_MEMBER_FUNCTION_POINTER_CV_HPP__
+#define __MOCKITOPP_REMOVE_MEMBER_FUNCTION_POINTER_CV_HPP__
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * Simple meta-prorgramming template that removes
+ * const/volatile from member function pointers
+ * making them suitable for internal use.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T>
+ struct remove_member_function_pointer_cv
+ { typedef T type; };
+
+ // 0 argument MFP remove const template
+ template <typename R, typename C>
+ struct remove_member_function_pointer_cv<R (C::*)() const>
+ { typedef R (C::*type)(); };
+
+ // 0 argument MFP remove const volatile template
+ template <typename R, typename C>
+ struct remove_member_function_pointer_cv<R (C::*)() const volatile>
+ { typedef R (C::*type)(); };
+
+ // 1 argument MFP remove const template
+ template <typename R, typename C, typename A0>
+ struct remove_member_function_pointer_cv<R (C::*)(A0) const>
+ { typedef R (C::*type)(A0); };
+
+ // 1 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0>
+ struct remove_member_function_pointer_cv<R (C::*)(A0) const volatile>
+ { typedef R (C::*type)(A0); };
+
+ // 2 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1) const>
+ { typedef R (C::*type)(A0, A1); };
+
+ // 2 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1) const volatile>
+ { typedef R (C::*type)(A0, A1); };
+
+ // 3 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2) const>
+ { typedef R (C::*type)(A0, A1, A2); };
+
+ // 3 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2) const volatile>
+ { typedef R (C::*type)(A0, A1, A2); };
+
+ // 4 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3) const>
+ { typedef R (C::*type)(A0, A1, A2, A3); };
+
+ // 4 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3) const volatile>
+ { typedef R (C::*type)(A0, A1, A2, A3); };
+
+ // 5 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4) const>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4); };
+
+ // 5 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4) const volatile>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4); };
+
+ // 6 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5) const>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5); };
+
+ // 6 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5) const volatile>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5); };
+
+ // 7 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6) const>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6); };
+
+ // 7 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6) const volatile>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6); };
+
+ // 8 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7) const>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6, A7); };
+
+ // 8 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7) const volatile>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6, A7); };
+
+ // 9 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8) const>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6, A7, A8); };
+
+ // 9 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8) const volatile>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6, A7, A8); };
+
+ // 10 argument MFP remove const template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) const>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9); };
+
+ // 10 argument MFP remove const volatile template
+ template <typename R, typename C, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ struct remove_member_function_pointer_cv<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) const volatile>
+ { typedef R (C::*type)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9); };
+
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_TR1_TYPE_TRAITS_HPP__
diff --git a/3rdparty/mockitopp/detail/util/remove_member_function_pointer_cv.hpp.m4 b/3rdparty/mockitopp/detail/util/remove_member_function_pointer_cv.hpp.m4
new file mode 100644
index 0000000..b9ee80d
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/remove_member_function_pointer_cv.hpp.m4
@@ -0,0 +1,38 @@
+#ifndef __MOCKITOPP_REMOVE_MEMBER_FUNCTION_POINTER_CV_HPP__
+#define __MOCKITOPP_REMOVE_MEMBER_FUNCTION_POINTER_CV_HPP__
+
+include(`mockitopp/detail/m4/ENUM_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/ENUM_TRAILING_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/REPEAT.m4')dnl
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * Simple meta-prorgramming template that removes
+ * const/volatile from member function pointers
+ * making them suitable for internal use.
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T>
+ struct remove_member_function_pointer_cv
+ { typedef T type; };
+
+define(`REMOVE_MFP_CV_TEMPLATE',
+` // $1 argument MFP remove const template
+ template <typename R, typename C`'M4_ENUM_TRAILING_PARAMS($1, typename A)>
+ struct remove_member_function_pointer_cv<R (C::*)(M4_ENUM_PARAMS($1, A)) const>
+ { typedef R (C::*type)(M4_ENUM_PARAMS($1, A)); };
+
+ // $1 argument MFP remove const volatile template
+ template <typename R, typename C`'M4_ENUM_TRAILING_PARAMS($1, typename A)>
+ struct remove_member_function_pointer_cv<R (C::*)(M4_ENUM_PARAMS($1, A)) const volatile>
+ { typedef R (C::*type)(M4_ENUM_PARAMS($1, A)); };
+
+')dnl
+M4_REPEAT(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY + 1), `REMOVE_MFP_CV_TEMPLATE')dnl
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_TR1_TYPE_TRAITS_HPP__
diff --git a/3rdparty/mockitopp/detail/util/tr1_tuple.hpp b/3rdparty/mockitopp/detail/util/tr1_tuple.hpp
new file mode 100644
index 0000000..6d519e9
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/tr1_tuple.hpp
@@ -0,0 +1,204 @@
+#ifndef __MOCKITOPP_TR1_TUPLE_HPP__
+#define __MOCKITOPP_TR1_TUPLE_HPP__
+
+#include <mockitopp/detail/util/tr1_type_traits.hpp>
+
+/**
+ * partial implementation of tr1 <tuple>
+ * for internal mockitopp use
+ *
+ * unsupported functionality:
+ *
+ * get
+ * make_tuple
+ * tie
+ * tuple_element
+ * tuple_size
+ */
+namespace mockitopp
+{
+ namespace detail
+ {
+ namespace tr1
+ {
+ struct tuple_null_type {};
+
+ template <typename H, typename T>
+ struct tuple_cons
+ {
+ H head_;
+ T tail_;
+
+ tuple_cons(typename add_reference<typename add_const<H>::type>::type head,
+ typename add_reference<typename add_const<T>::type>::type tail)
+ : head_(head)
+ , tail_(tail)
+ {}
+ };
+
+ // 10 element template
+ template <typename T0 = tuple_null_type, typename T1 = tuple_null_type, typename T2 = tuple_null_type, typename T3 = tuple_null_type, typename T4 = tuple_null_type, typename T5 = tuple_null_type, typename T6 = tuple_null_type, typename T7 = tuple_null_type, typename T8 = tuple_null_type, typename T9 = tuple_null_type>
+ struct tuple : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, tuple_null_type> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2, typename add_reference<typename add_const<T3 >::type>::type t3, typename add_reference<typename add_const<T4 >::type>::type t4, typename add_reference<typename add_const<T5 >::type>::type t5, typename add_reference<typename add_const<T6 >::type>::type t6, typename add_reference<typename add_const<T7 >::type>::type t7, typename add_reference<typename add_const<T8 >::type>::type t8, typename add_reference<typename add_const<T9 >::type>::type t9)
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, tuple_null_type> >
+ (t0, tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, tuple_null_type>
+ (t1, t2, t3, t4, t5, t6, t7, t8, t9))
+ {}
+ };
+
+ // 2 element template
+ template <typename T0, typename T1>
+ struct tuple<T0, T1 , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple<T1> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1)
+ : tuple_cons<T0, tuple<T1> >
+ (t0, tuple<T1>
+ (t1))
+ {}
+ };
+
+ // 3 element template
+ template <typename T0, typename T1, typename T2>
+ struct tuple<T0, T1, T2 , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple<T1, T2> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2)
+ : tuple_cons<T0, tuple<T1, T2> >
+ (t0, tuple<T1, T2>
+ (t1, t2))
+ {}
+ };
+
+ // 4 element template
+ template <typename T0, typename T1, typename T2, typename T3>
+ struct tuple<T0, T1, T2, T3 , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple<T1, T2, T3> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2, typename add_reference<typename add_const<T3 >::type>::type t3)
+ : tuple_cons<T0, tuple<T1, T2, T3> >
+ (t0, tuple<T1, T2, T3>
+ (t1, t2, t3))
+ {}
+ };
+
+ // 5 element template
+ template <typename T0, typename T1, typename T2, typename T3, typename T4>
+ struct tuple<T0, T1, T2, T3, T4 , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple<T1, T2, T3, T4> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2, typename add_reference<typename add_const<T3 >::type>::type t3, typename add_reference<typename add_const<T4 >::type>::type t4)
+ : tuple_cons<T0, tuple<T1, T2, T3, T4> >
+ (t0, tuple<T1, T2, T3, T4>
+ (t1, t2, t3, t4))
+ {}
+ };
+
+ // 6 element template
+ template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
+ struct tuple<T0, T1, T2, T3, T4, T5 , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2, typename add_reference<typename add_const<T3 >::type>::type t3, typename add_reference<typename add_const<T4 >::type>::type t4, typename add_reference<typename add_const<T5 >::type>::type t5)
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5> >
+ (t0, tuple<T1, T2, T3, T4, T5>
+ (t1, t2, t3, t4, t5))
+ {}
+ };
+
+ // 7 element template
+ template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+ struct tuple<T0, T1, T2, T3, T4, T5, T6 , tuple_null_type , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2, typename add_reference<typename add_const<T3 >::type>::type t3, typename add_reference<typename add_const<T4 >::type>::type t4, typename add_reference<typename add_const<T5 >::type>::type t5, typename add_reference<typename add_const<T6 >::type>::type t6)
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6> >
+ (t0, tuple<T1, T2, T3, T4, T5, T6>
+ (t1, t2, t3, t4, t5, t6))
+ {}
+ };
+
+ // 8 element template
+ template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+ struct tuple<T0, T1, T2, T3, T4, T5, T6, T7 , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6, T7> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2, typename add_reference<typename add_const<T3 >::type>::type t3, typename add_reference<typename add_const<T4 >::type>::type t4, typename add_reference<typename add_const<T5 >::type>::type t5, typename add_reference<typename add_const<T6 >::type>::type t6, typename add_reference<typename add_const<T7 >::type>::type t7)
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6, T7> >
+ (t0, tuple<T1, T2, T3, T4, T5, T6, T7>
+ (t1, t2, t3, t4, t5, t6, t7))
+ {}
+ };
+
+ // 9 element template
+ template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
+ struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8 , tuple_null_type>
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6, T7, T8> >
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0, typename add_reference<typename add_const<T1 >::type>::type t1, typename add_reference<typename add_const<T2 >::type>::type t2, typename add_reference<typename add_const<T3 >::type>::type t3, typename add_reference<typename add_const<T4 >::type>::type t4, typename add_reference<typename add_const<T5 >::type>::type t5, typename add_reference<typename add_const<T6 >::type>::type t6, typename add_reference<typename add_const<T7 >::type>::type t7, typename add_reference<typename add_const<T8 >::type>::type t8)
+ : tuple_cons<T0, tuple<T1, T2, T3, T4, T5, T6, T7, T8> >
+ (t0, tuple<T1, T2, T3, T4, T5, T6, T7, T8>
+ (t1, t2, t3, t4, t5, t6, t7, t8))
+ {}
+ };
+
+
+
+ // 1 element template
+ template <typename T0>
+ struct tuple<T0 , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type>
+ : tuple_cons<T0, tuple_null_type>
+ {
+ tuple(typename add_reference<typename add_const<T0 >::type>::type t0)
+ : tuple_cons<T0, tuple_null_type>
+ (t0, tuple_null_type())
+ {}
+ };
+
+ // 0 element template
+ template <>
+ struct tuple< tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type , tuple_null_type >
+ : tuple_cons<tuple_null_type, tuple_null_type>
+ {
+ tuple()
+ : tuple_cons<tuple_null_type, tuple_null_type>
+ (tuple_null_type(), tuple_null_type())
+ {}
+ };
+ } // namespace tr1
+ } // namespace detail
+} // namespace mockitopp
+
+inline bool operator== (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true; }
+inline bool operator!= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
+inline bool operator< (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
+inline bool operator<= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true; }
+inline bool operator> (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
+inline bool operator>= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true; }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator== (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs.head_ == rhs.head_) && (lhs.tail_ == rhs.tail_); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator!= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return !(lhs == rhs); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator< (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs.head_ < rhs.head_) || (lhs.tail_ < rhs.tail_); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator<= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs == rhs) || (lhs < rhs); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator> (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs.head_ > rhs.head_) && (lhs.tail_ > rhs.tail_); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator>= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs == rhs) || (lhs > rhs); }
+
+#endif //__MOCKITOPP_TR1_TUPLE_HPP__
diff --git a/3rdparty/mockitopp/detail/util/tr1_tuple.hpp.m4 b/3rdparty/mockitopp/detail/util/tr1_tuple.hpp.m4
new file mode 100644
index 0000000..5e9e969
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/tr1_tuple.hpp.m4
@@ -0,0 +1,129 @@
+#ifndef __MOCKITOPP_TR1_TUPLE_HPP__
+#define __MOCKITOPP_TR1_TUPLE_HPP__
+
+#include <mockitopp/detail/util/tr1_type_traits.hpp>
+
+include(`mockitopp/detail/m4/ENUM_BINARY_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/ENUM_SHIFTED_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/ENUM_PARAMS.m4')dnl
+include(`mockitopp/detail/m4/REPEAT.m4')dnl
+include(`mockitopp/detail/m4/REPEAT_FROM_TO.m4')dnl
+/**
+ * partial implementation of tr1 <tuple>
+ * for internal mockitopp use
+ *
+ * unsupported functionality:
+ *
+ * get
+ * make_tuple
+ * tie
+ * tuple_element
+ * tuple_size
+ */
+namespace mockitopp
+{
+ namespace detail
+ {
+ namespace tr1
+ {
+ struct tuple_null_type {};
+
+ template <typename H, typename T>
+ struct tuple_cons
+ {
+ H head_;
+ T tail_;
+
+ tuple_cons(typename add_reference<typename add_const<H>::type>::type head,
+ typename add_reference<typename add_const<T>::type>::type tail)
+ : head_(head)
+ , tail_(tail)
+ {}
+ };
+
+ // MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY element template
+ template <M4_ENUM_BINARY_PARAMS(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY, typename T, = tuple_null_type, M4_INTERCEPT)>
+ struct tuple : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), T), tuple_null_type> >
+ {
+ tuple(M4_ENUM_BINARY_PARAMS(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY, typename add_reference<typename add_const<T, >::type>::type t))
+ : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), T), tuple_null_type> >
+ (t0, tuple<M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), T), tuple_null_type>
+ (M4_ENUM_SHIFTED_PARAMS(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), t)))
+ {}
+ };
+
+define(`TUPLE_NULL_TYPE_TRAILING_PARAM', `, tuple_null_type')dnl
+define(`TUPLE_TEMPLATE',
+` // $1 element template
+ template <M4_ENUM_PARAMS($1, typename T)>
+ struct tuple<M4_ENUM_PARAMS($1, T)M4_REPEAT(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY-$1), `TUPLE_NULL_TYPE_TRAILING_PARAM')>
+ : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS($1, T)> >
+ {
+ tuple(M4_ENUM_BINARY_PARAMS($1, typename add_reference<typename add_const<T, >::type>::type t))
+ : tuple_cons<T0, tuple<M4_ENUM_SHIFTED_PARAMS($1, T)> >
+ (t0, tuple<M4_ENUM_SHIFTED_PARAMS($1, T)>
+ (M4_ENUM_SHIFTED_PARAMS($1, t)))
+ {}
+ };
+
+')dnl
+M4_REPEAT_FROM_TO(2, eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY), `TUPLE_TEMPLATE')
+
+ // 1 element template
+ template <M4_ENUM_PARAMS(1, typename T)>
+ struct tuple<M4_ENUM_PARAMS(1, T)M4_REPEAT(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY - 1), `TUPLE_NULL_TYPE_TRAILING_PARAM')>
+ : tuple_cons<T0, tuple_null_type>
+ {
+ tuple(M4_ENUM_BINARY_PARAMS(1, typename add_reference<typename add_const<T, >::type>::type t))
+ : tuple_cons<T0, tuple_null_type>
+ (t0, tuple_null_type())
+ {}
+ };
+
+ // 0 element template
+define(`TUPLE_NULL_TYPE_PARAM', `tuple_null_type M4_COMMA_IF(eval(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY-1-$1))')dnl
+ template <>
+ struct tuple<M4_REPEAT(MOCKITOPP_MAX_VIRTUAL_FUNCTION_ARITY, `TUPLE_NULL_TYPE_PARAM')>
+ : tuple_cons<tuple_null_type, tuple_null_type>
+ {
+ tuple()
+ : tuple_cons<tuple_null_type, tuple_null_type>
+ (tuple_null_type(), tuple_null_type())
+ {}
+ };
+ } // namespace tr1
+ } // namespace detail
+} // namespace mockitopp
+
+inline bool operator== (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true; }
+inline bool operator!= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
+inline bool operator< (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
+inline bool operator<= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true; }
+inline bool operator> (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return false; }
+inline bool operator>= (const mockitopp::detail::tr1::tuple_null_type&, const mockitopp::detail::tr1::tuple_null_type&) { return true; }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator== (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs.head_ == rhs.head_) && (lhs.tail_ == rhs.tail_); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator!= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return !(lhs == rhs); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator< (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs.head_ < rhs.head_) || (lhs.tail_ < rhs.tail_); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator<= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs == rhs) || (lhs < rhs); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator> (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs.head_ > rhs.head_) && (lhs.tail_ > rhs.tail_); }
+
+template <typename L0, typename L1, typename R0, typename R1>
+inline bool operator>= (const mockitopp::detail::tr1::tuple_cons<L0, L1>& lhs, const mockitopp::detail::tr1::tuple_cons<R0, R1>& rhs)
+ { return (lhs == rhs) || (lhs > rhs); }
+
+#endif //__MOCKITOPP_TR1_TUPLE_HPP__
diff --git a/3rdparty/mockitopp/detail/util/tr1_type_traits.hpp b/3rdparty/mockitopp/detail/util/tr1_type_traits.hpp
new file mode 100644
index 0000000..6e8b3f6
--- /dev/null
+++ b/3rdparty/mockitopp/detail/util/tr1_type_traits.hpp
@@ -0,0 +1,45 @@
+#ifndef __MOCKITOPP_TR1_TYPE_TRAITS_HPP__
+#define __MOCKITOPP_TR1_TYPE_TRAITS_HPP__
+
+namespace mockitopp
+{
+ namespace detail
+ {
+ /**
+ * Simple subset adaptation of tr1 type_traits
+ * for internal mockitopp use.
+ *
+ * @author Trevor Pounds
+ * @see http://www.boost.org/doc/libs/release/libs/type_traits/
+ */
+ namespace tr1
+ {
+ #ifdef _MSC_VER
+ // C4181: qualifier applied to reference type
+ #pragma warning(disable:4181)
+ #endif
+
+ // std::tr1::add_const
+ template <typename T> struct add_const { typedef const T type; };
+ template <typename T> struct add_const<const T> { typedef const T type; };
+
+ #ifdef _MSC_VER
+ #pragma warning(default:4181)
+ #endif
+
+ // std::tr1::remove_const
+ template <typename T> struct remove_const { typedef T type; };
+ template <typename T> struct remove_const<const T> { typedef T type; };
+
+ // std::tr1::add_reference
+ template <typename T> struct add_reference { typedef T type; };
+ template <typename T> struct add_reference<T&> { typedef T& type; };
+
+ // std::tr1::remove_reference
+ template <typename T> struct remove_reference { typedef T type; };
+ template <typename T> struct remove_reference<T&> { typedef T type; };
+ } // namespace tr1
+ } // namespace detail
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_TR1_TYPE_TRAITS_HPP__
diff --git a/3rdparty/mockitopp/exceptions.hpp b/3rdparty/mockitopp/exceptions.hpp
new file mode 100644
index 0000000..d298149
--- /dev/null
+++ b/3rdparty/mockitopp/exceptions.hpp
@@ -0,0 +1,20 @@
+#ifndef __MOCKITOPP_EXCEPTIONS_HPP__
+#define __MOCKITOPP_EXCEPTIONS_HPP__
+
+#include <exception>
+
+namespace mockitopp
+{
+ #define MOCKITO_EXCEPTION(EEE) struct EEE : public ::std::exception {};
+
+ MOCKITO_EXCEPTION(partial_implementation_exception)
+ MOCKITO_EXCEPTION(missing_implementation_exception)
+
+ MOCKITO_EXCEPTION(less_invocations_expected);
+ MOCKITO_EXCEPTION(more_invocations_expected);
+ MOCKITO_EXCEPTION(zero_invocations_expected);
+
+ #undef MOCKITO_EXCEPTION
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_EXCEPTIONS_HPP__
diff --git a/3rdparty/mockitopp/matchers.hpp b/3rdparty/mockitopp/matchers.hpp
new file mode 100644
index 0000000..88e320e
--- /dev/null
+++ b/3rdparty/mockitopp/matchers.hpp
@@ -0,0 +1,10 @@
+#ifndef __MOCKITOPP_MATCHERS_HPP__
+#define __MOCKITOPP_MATCHERS_HPP__
+
+#include <mockitopp/matchers/base/any.hpp>
+#include <mockitopp/matchers/base/equal.hpp>
+#include <mockitopp/matchers/base/is_not.hpp>
+#include <mockitopp/matchers/base/null.hpp>
+#include <mockitopp/matchers/type/string_literal.hpp>
+
+#endif //__MOCKITOPP_MATCHERS_HPP__
diff --git a/3rdparty/mockitopp/matchers/Matcher.hpp b/3rdparty/mockitopp/matchers/Matcher.hpp
new file mode 100644
index 0000000..7ce8aba
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/Matcher.hpp
@@ -0,0 +1,22 @@
+#ifndef __MOCKITOPP_MATCHER_HPP__
+#define __MOCKITOPP_MATCHER_HPP__
+
+#include <mockitopp/detail/util/tr1_type_traits.hpp>
+
+namespace mockitopp
+{
+ namespace matcher
+ {
+ template <typename T>
+ struct Matcher
+ {
+ virtual ~Matcher() {};
+
+ virtual Matcher* clone() const = 0;
+
+ virtual bool operator== (typename mockitopp::detail::tr1::add_reference<typename mockitopp::detail::tr1::add_const<T>::type>::type rhs) const = 0;
+ };
+ } // namespace matcher
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MATCHER_HPP__
diff --git a/3rdparty/mockitopp/matchers/base/any.hpp b/3rdparty/mockitopp/matchers/base/any.hpp
new file mode 100644
index 0000000..946f457
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/base/any.hpp
@@ -0,0 +1,35 @@
+#ifndef __MOCKITOPP_MATCHER_ANY_HPP__
+#define __MOCKITOPP_MATCHER_ANY_HPP__
+
+#include <mockitopp/matchers/Matcher.hpp>
+
+namespace mockitopp
+{
+ namespace matcher
+ {
+ namespace detail
+ {
+ template <typename T>
+ struct AnyT : public Matcher<T>
+ {
+ AnyT()
+ {}
+
+ virtual Matcher<T>* clone() const
+ { return new AnyT(); }
+
+ virtual bool operator== (typename mockitopp::detail::tr1::add_reference<typename mockitopp::detail::tr1::add_const<T>::type>::type rhs) const
+ {
+ (void)rhs;
+ return true;
+ }
+ };
+ } // namespace detail
+
+ template <typename T>
+ detail::AnyT<T> any()
+ { return detail::AnyT<T>(); }
+ } // namespace matcher
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MATCHER_ANY_HPP__
diff --git a/3rdparty/mockitopp/matchers/base/equal.hpp b/3rdparty/mockitopp/matchers/base/equal.hpp
new file mode 100644
index 0000000..2e9d3c6
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/base/equal.hpp
@@ -0,0 +1,44 @@
+#ifndef __MOCKITOPP_MATCHER_EQ_HPP__
+#define __MOCKITOPP_MATCHER_EQ_HPP__
+
+#include <mockitopp/matchers/Matcher.hpp>
+#include <string>
+
+namespace mockitopp
+{
+ namespace matcher
+ {
+ namespace detail
+ {
+ template <typename T>
+ struct EqualT : public Matcher<T>
+ {
+ EqualT(typename mockitopp::detail::tr1::add_reference<
+ typename mockitopp::detail::tr1::add_const<T>::type>::type element)
+ : element_(element)
+ {}
+
+ virtual Matcher<T>* clone() const
+ { return new EqualT(element_); }
+
+ virtual bool operator== (typename mockitopp::detail::tr1::add_reference<
+ typename mockitopp::detail::tr1::add_const<T>::type>::type rhs) const
+ { return element_ == rhs; }
+
+ private:
+
+ T element_;
+ };
+ } // namespace detail
+
+ template <typename T>
+ detail::EqualT<T> equal(typename mockitopp::detail::tr1::add_reference<
+ typename mockitopp::detail::tr1::add_const<T>::type>::type element)
+ { return detail::EqualT<T>(element); }
+
+ inline detail::EqualT<std::string> equal(const char* element)
+ { return detail::EqualT<std::string>(element); }
+ } // namespace matcher
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MATCHER_EQ_HPP__
diff --git a/3rdparty/mockitopp/matchers/base/is_not.hpp b/3rdparty/mockitopp/matchers/base/is_not.hpp
new file mode 100644
index 0000000..e951200
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/base/is_not.hpp
@@ -0,0 +1,40 @@
+#ifndef __MOCKITOPP_MATCHER_NOT_HPP__
+#define __MOCKITOPP_MATCHER_NOT_HPP__
+
+#include <mockitopp/matchers/Matcher.hpp>
+
+namespace mockitopp
+{
+ namespace matcher
+ {
+ namespace detail
+ {
+ template <typename T>
+ struct NotT : public Matcher<T>
+ {
+ NotT(const Matcher<T>& matcher)
+ : matcher_(matcher.clone())
+ {}
+
+ virtual ~NotT()
+ { delete matcher_; }
+
+ virtual Matcher<T>* clone() const
+ { return new NotT(*matcher_); }
+
+ virtual bool operator== (typename mockitopp::detail::tr1::add_reference<typename mockitopp::detail::tr1::add_const<T>::type>::type rhs) const
+ { return !(*matcher_ == rhs); }
+
+ private:
+
+ Matcher<T>* matcher_;
+ };
+ } // namespace detail
+
+ template <typename T>
+ detail::NotT<T> is_not(const Matcher<T>& matcher)
+ { return detail::NotT<T>(matcher); }
+ } // namespace matcher
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MATCHER_EQ_HPP__
diff --git a/3rdparty/mockitopp/matchers/base/null.hpp b/3rdparty/mockitopp/matchers/base/null.hpp
new file mode 100644
index 0000000..96ec290
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/base/null.hpp
@@ -0,0 +1,32 @@
+#ifndef __MOCKITOPP_MATCHER_NULL_HPP__
+#define __MOCKITOPP_MATCHER_NULL_HPP__
+
+#include <mockitopp/matchers/Matcher.hpp>
+
+namespace mockitopp
+{
+ namespace matcher
+ {
+ namespace detail
+ {
+ template <typename T>
+ struct NullT : public Matcher<T>
+ {
+ NullT()
+ {}
+
+ virtual Matcher<T>* clone() const
+ { return new NullT(); }
+
+ virtual bool operator== (typename mockitopp::detail::tr1::add_reference<typename mockitopp::detail::tr1::add_const<T>::type>::type rhs) const
+ { return rhs == 0; }
+ };
+ } // namespace detail
+
+ template <typename T>
+ detail::NullT<T> null()
+ { return detail::NullT<T>(); }
+ } // namespace matcher
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MATCHER_NULL_HPP__
diff --git a/3rdparty/mockitopp/matchers/regex.hpp b/3rdparty/mockitopp/matchers/regex.hpp
new file mode 100644
index 0000000..ec7e00f
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/regex.hpp
@@ -0,0 +1,51 @@
+#ifndef __MOCKITOPP_MATCHER_REGEX_HPP__
+#define __MOCKITOPP_MATCHER_REGEX_HPP__
+
+#include <mockitopp/matchers/Matcher.hpp>
+
+namespace mockitopp
+{
+ namespace matcher
+ {
+ namespace detail
+ {
+ #if defined(BOOST_RE_REGEX_HPP)
+ namespace __tr1 = ::boost;
+ #elif defined(_GLIBCXX_TR1_REGEX) || defined(_REGEX_)
+ namespace __tr1 = ::std::tr1;
+ #elif defined(_GLIBCXX_REGEX)
+ namespace __tr1 = ::std;
+ #else
+ #error compatible tr1 regex header not found!
+ #endif
+
+ template <typename T>
+ struct RegexT : public Matcher<T>
+ {
+ RegexT(typename mockitopp::detail::tr1::add_reference<typename mockitopp::detail::tr1::add_const<T>::type>::type expr)
+ : expr_(expr)
+ {}
+
+ virtual Matcher<T>* clone() const
+ { return new RegexT(expr_); }
+
+ virtual bool operator== (typename mockitopp::detail::tr1::add_reference<typename mockitopp::detail::tr1::add_const<T>::type>::type rhs) const
+ { return __tr1::regex_match(rhs, expr_); }
+
+ private:
+
+ __tr1::regex expr_;
+
+ RegexT(const __tr1::regex& expr)
+ : expr_(expr)
+ {}
+ };
+ } // namespace detail
+
+ template <typename T>
+ detail::RegexT<T> regex(T expr)
+ { return detail::RegexT<T>(expr); }
+ } // namespace matcher
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MATCHER_REGEX_HPP__
diff --git a/3rdparty/mockitopp/matchers/type/std_container.hpp b/3rdparty/mockitopp/matchers/type/std_container.hpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/type/std_container.hpp
diff --git a/3rdparty/mockitopp/matchers/type/std_string.hpp b/3rdparty/mockitopp/matchers/type/std_string.hpp
new file mode 100644
index 0000000..8561b69
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/type/std_string.hpp
@@ -0,0 +1,3 @@
+starts_with()
+ends_with()
+contains()
diff --git a/3rdparty/mockitopp/matchers/type/string_literal.hpp b/3rdparty/mockitopp/matchers/type/string_literal.hpp
new file mode 100644
index 0000000..8b942bd
--- /dev/null
+++ b/3rdparty/mockitopp/matchers/type/string_literal.hpp
@@ -0,0 +1,42 @@
+#ifndef __MOCKITOPP_MATCHER_STRING_LITERAL_HPP__
+#define __MOCKITOPP_MATCHER_STRING_LITERAL_HPP__
+
+#include <mockitopp/matchers/Matcher.hpp>
+#include <string>
+
+namespace mockitopp
+{
+ namespace matcher
+ {
+ namespace detail
+ {
+ template <typename T> struct is_string_literal {};
+ template <> struct is_string_literal<char*> { typedef char* type; };
+ template <> struct is_string_literal<const char*> { typedef const char* type; };
+
+ template <typename T>
+ struct StringLiteralT : public Matcher<T>
+ {
+ StringLiteralT(const T& string_lit)
+ : internal_string(string_lit)
+ {}
+
+ virtual Matcher<T>* clone() const
+ { return new StringLiteralT(const_cast<T>(internal_string.c_str())); }
+
+ virtual bool operator== (typename mockitopp::detail::tr1::add_reference<typename mockitopp::detail::tr1::add_const<T>::type>::type rhs) const
+ { return internal_string == rhs; }
+
+ private:
+
+ std::string internal_string;
+ };
+ } // namespace detail
+
+ template <typename T>
+ detail::StringLiteralT<T> string_literal(typename detail::is_string_literal<T>::type string_lit)
+ { return detail::StringLiteralT<T>(string_lit); }
+ } // namespace matcher
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MATCHER_STRING_LITERAL_HPP__
diff --git a/3rdparty/mockitopp/mock_object.hpp b/3rdparty/mockitopp/mock_object.hpp
new file mode 100644
index 0000000..2368469
--- /dev/null
+++ b/3rdparty/mockitopp/mock_object.hpp
@@ -0,0 +1,45 @@
+#ifndef __MOCKITOPP_MOCK_OBJECT_HPP__
+#define __MOCKITOPP_MOCK_OBJECT_HPP__
+
+#include <mockitopp/detail/stubbing/dynamic_object.hpp>
+
+/**
+* helper macro to make mocking of overloaded functions less verbose
+*/
+#define overloaded_method(return_type, type, method, ...) \
+ static_cast<return_type (type::*)(__VA_ARGS__)>(&type::method)
+
+namespace mockitopp
+{
+ /**
+ * provides a base implementation of a mock object
+ *
+ * @author Trevor Pounds
+ */
+ template <typename T>
+ struct mock_object : protected detail::dynamic_object
+ {
+ /**
+ * returns a mock object of the given abstract base class/interface
+ *
+ * @return mock object
+ */
+ T& getInstance()
+ { return reinterpret_cast<T&>(*this); }
+
+ /**
+ * stub functionality for a given method
+ *
+ * @param ptr2member method to be stubbed
+ */
+ template <typename M>
+ detail::dynamic_vfunction<typename detail::remove_member_function_pointer_cv<M>::type>& expect(M ptr2member)
+ { return define_function(ptr2member); }
+
+ template <typename M>
+ detail::dynamic_vfunction<typename detail::remove_member_function_pointer_cv<M>::type>& operator() (M ptr2member)
+ { return expect(ptr2member); }
+ };
+} // namespace mockitopp
+
+#endif //__MOCKITOPP_MOCK_OBJECT_HPP__
diff --git a/3rdparty/mockitopp/mockitopp.hpp b/3rdparty/mockitopp/mockitopp.hpp
new file mode 100644
index 0000000..444d04d
--- /dev/null
+++ b/3rdparty/mockitopp/mockitopp.hpp
@@ -0,0 +1,8 @@
+#ifndef __MOCKITOPP_HPP__
+#define __MOCKITOPP_HPP__
+
+#include "exceptions.hpp"
+#include "matchers.hpp"
+#include "mock_object.hpp"
+
+#endif //__MOCKITOPP_HPP__
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82abf34..e643b72 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,3 +18,4 @@
add_subdirectory(src)
add_subdirectory(tests)
+add_subdirectory(3rdparty)
diff --git a/src/utils/mockobject.h b/src/utils/mockobject.h
new file mode 100644
index 0000000..f8c637d
--- /dev/null
+++ b/src/utils/mockobject.h
@@ -0,0 +1,79 @@
+/* This file is part of Zanshin
+
+ Copyright 2014 Kevin Ottens <ervin@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License or (at your option) version 3 or any later version
+ accepted by the membership of KDE e.V. (or its successor approved
+ by the membership of KDE e.V.), which shall act as a proxy
+ defined in Section 14 of version 3 of the license.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+*/
+
+
+#ifndef UTILS_MOCKOBJECT_H
+#define UTILS_MOCKOBJECT_H
+
+#include <mockitopp/mockitopp.hpp>
+
+#include <QSharedPointer>
+
+namespace Utils {
+ template<typename T>
+ class MockObject
+ {
+ typedef mockitopp::mock_object<T> InternalMockType;
+
+ class InternalDeleter
+ {
+ public:
+ explicit InternalDeleter(InternalMockType *mockObject)
+ : m_mockObject(mockObject)
+ {
+ }
+
+ void operator ()(T *)
+ {
+ delete m_mockObject;
+ }
+
+ private:
+ InternalMockType *m_mockObject;
+ };
+
+ public:
+ MockObject()
+ : m_mockObject(new InternalMockType),
+ m_mockPtr(&m_mockObject->getInstance(), InternalDeleter(m_mockObject))
+ {
+ }
+
+ QSharedPointer<T> getInstance()
+ {
+ return m_mockPtr;
+ }
+
+ template <typename M>
+ mockitopp::detail::dynamic_vfunction<typename mockitopp::detail::remove_member_function_pointer_cv<M>::type>& operator() (M ptr2member)
+ {
+ return (*m_mockObject)(ptr2member);
+ }
+
+ private:
+ InternalMockType *m_mockObject;
+ QSharedPointer<T> m_mockPtr;
+ };
+}
+
+#endif // UTILS_MOCKOBJECT_H