diff --git a/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp b/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp index 8bd3fb72..de16e308 100644 --- a/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp +++ b/3rdparty/mockitopp/detail/stubbing/dynamic_object.hpp @@ -1,139 +1,143 @@ #ifndef __MOCKITOPP_DYNAMIC_OBJECT_HPP__ #define __MOCKITOPP_DYNAMIC_OBJECT_HPP__ #include #include #include #include namespace mockitopp { namespace detail { /** * helper class to find the vtable offset given a member function pointer */ struct vtable_offset_helper { template static int get(T ptr2member) { vtable_offset_helper f; return (f.*reinterpret_cast(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(&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(vtable_mocks[i]); } } delete vtable_actual_ptr; } template dynamic_vfunction::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::get(ptr2member); vtable_mocks[offset] = new dynamic_vfunction::type>(); } return *reinterpret_cast::type>*>(vtable_mocks[offset]); } void missing_vfunction() { throw missing_implementation_exception(); } + + private: + dynamic_object(const dynamic_object &); + dynamic_object &operator=(const dynamic_object &); }; } // 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 index 92a425da..6b871975 100644 --- a/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp +++ b/3rdparty/mockitopp/detail/stubbing/dynamic_vfunction.hpp @@ -1,1194 +1,1197 @@ #ifndef __MOCKITOPP_DYNAMIC_VFUNCTION_HPP__ #define __MOCKITOPP_DYNAMIC_VFUNCTION_HPP__ #include #include #include #include #include #include #include // 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 struct dynamic_vfunction_progress : dynamic_vfunction_base { typedef shared_ptr > action_type; typedef std::list action_queue_type; action_queue_type* stubbing_progress; dynamic_vfunction_progress& thenReturn(R value) { stubbing_progress->push_back(action_type(new returnable_action(value))); return *this; } template dynamic_vfunction_progress& thenThrow(T throwable) { stubbing_progress->push_back(action_type(new throwable_action(throwable))); return *this; } }; template <> struct dynamic_vfunction_progress : dynamic_vfunction_base { typedef shared_ptr > action_type; typedef std::list action_queue_type; action_queue_type* stubbing_progress; dynamic_vfunction_progress& thenReturn() { stubbing_progress->push_back(action_type(new returnable_action())); return *this; } template dynamic_vfunction_progress& thenThrow(T throwable) { stubbing_progress->push_back(action_type(new throwable_action(throwable))); return *this; } }; template struct map_entry { K key; V val; map_entry(const K& k, const V& v) : key(k), val(v) {} template bool operator== (const map_entry& rhs) const { return key == rhs.key; } template bool operator== (const T& rhs) const { return key == rhs; } }; template struct matcher_element { matcher::Matcher* matcher; matcher_element(const matcher::Matcher& _matcher) : matcher(_matcher.clone()) {} matcher_element(const matcher_element& rhs) : matcher(rhs.matcher->clone()) {} ~matcher_element() { delete matcher; } + matcher_element &operator= (const matcher_element& rhs) const + { matcher_element tmp(rhs); std::swap(*this, tmp); return *this; } + bool operator== (typename tr1::add_reference::type>::type rhs) const { return (*matcher == rhs); } bool operator== (const matcher_element& rhs) const { return (matcher == rhs.matcher); } }; template struct dynamic_vfunction; // TODO: clean up impl // TODO: add sequence matcher // TODO: clean up typedef nomenclature // 0 arity template template struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple<> exact_tuple_type; typedef tr1::tuple< > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when() { const exact_tuple_type args = exact_tuple_type(); typename std::list >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& when(A0 a0) { const exact_tuple_type args = exact_tuple_type(a0); typename std::list >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& when(A0 a0, A1 a1) { const exact_tuple_type args = exact_tuple_type(a0, a1); typename std::list >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& when(A0 a0, A1 a1, A2 a2) { const exact_tuple_type args = exact_tuple_type(a0, a1, a2); typename std::list >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2, const matcher::Matcher& a3) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& when(A0 a0, A1 a1, A2 a2, A3 a3) { const exact_tuple_type args = exact_tuple_type(a0, a1, a2, a3); typename std::list >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2, const matcher::Matcher& a3, const matcher::Matcher& a4) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& 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 >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2, const matcher::Matcher& a3, const matcher::Matcher& a4, const matcher::Matcher& a5) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& 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 >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2, const matcher::Matcher& a3, const matcher::Matcher& a4, const matcher::Matcher& a5, const matcher::Matcher& a6) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& 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 >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2, const matcher::Matcher& a3, const matcher::Matcher& a4, const matcher::Matcher& a5, const matcher::Matcher& a6, const matcher::Matcher& a7) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& 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 >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2, const matcher::Matcher& a3, const matcher::Matcher& a4, const matcher::Matcher& a5, const matcher::Matcher& a6, const matcher::Matcher& a7, const matcher::Matcher& a8) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& 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 >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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 struct dynamic_vfunction : private dynamic_vfunction_progress { typedef tr1::tuple exact_tuple_type; typedef tr1::tuple, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element, matcher_element > fuzzy_tuple_type; typedef typename dynamic_vfunction_progress::action_type action_type; typedef typename dynamic_vfunction_progress::action_queue_type action_queue_type; std::list > exact_matches; std::list > fuzzy_matches; std::list > args_to_calls; dynamic_vfunction() : dynamic_vfunction_progress() , exact_matches() , fuzzy_matches() {} template int calculate_calls_for_arguments(const T args) { int calls = 0; typename std::list >::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& when(const matcher::Matcher& a0, const matcher::Matcher& a1, const matcher::Matcher& a2, const matcher::Matcher& a3, const matcher::Matcher& a4, const matcher::Matcher& a5, const matcher::Matcher& a6, const matcher::Matcher& a7, const matcher::Matcher& a8, const matcher::Matcher& a9) { const fuzzy_tuple_type args = fuzzy_tuple_type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); typename std::list >::iterator match = std::find(fuzzy_matches.begin(), fuzzy_matches.end(), args); if(match == fuzzy_matches.end()) { fuzzy_matches.push_back(map_entry(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& 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 >::iterator match = std::find(exact_matches.begin(), exact_matches.end(), args); if(match == exact_matches.end()) { exact_matches.push_back(map_entry(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 >::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(args, 1)); } else { (calls_it->val)++; } action_queue_type* actions = 0; typename std::list >::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 >::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/util/pointers.hpp b/3rdparty/mockitopp/detail/util/pointers.hpp index 85671ee2..ab4e3fed 100644 --- a/3rdparty/mockitopp/detail/util/pointers.hpp +++ b/3rdparty/mockitopp/detail/util/pointers.hpp @@ -1,225 +1,238 @@ #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 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 > 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(const shared_ptr_impl &other) + : _raw_ptr(other._raw_ptr) + , _count(other._count) + {} + ~shared_ptr_impl() { D()(_raw_ptr); } + + shared_ptr_impl &operator=(const shared_ptr_impl &other) + { + shared_ptr_impl tmp(other); + std::swap(*this, other); + return *this; + } + }* _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 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 > class shared_array : public shared_ptr { public: shared_array() : shared_ptr() {} explicit shared_array(T* raw_ptr) : shared_ptr(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 > 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 > class owned_array : public owned_ptr { public: owned_array() : owned_ptr() {} explicit owned_array(T* ptr) : owned_ptr(ptr) {} T& operator[] (size_t i) const { return *(owned_array::get() + i); } }; } // namespace detail } // namespace mockitopp #endif //__MOCKITOPP_POINTERS_PTR__