-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhippomocks.h
6411 lines (6199 loc) · 385 KB
/
hippomocks.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// HippoMocks, a library for using mocks in unit testing of C++ code.
// Copyright (C) 2008, Bas van Tiel, Christian Rexwinkel, Mike Looijmans,
// Peter Bindels
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// You can also retrieve it from http://www.gnu.org/licenses/lgpl-2.1.html
#ifndef HIPPOMOCKS_H
#define HIPPOMOCKS_H
// If you want to put all HippoMocks symbols into the global namespace, use the define below.
//#define NO_HIPPOMOCKS_NAMESPACE
// The DEFAULT_AUTOEXPECT is an option that determines whether tests are, by default, under- or
// overspecified. Auto-expect, by function, adds an expectation to the current ExpectCall that
// it will happen after the previous ExpectCall. For many people this is an intuitive and logical
// thing when writing a C++ program. Usually, this makes your test workable but overspecified.
// Overspecified means that your test will fail on working code that does things in a different
// order. The alternative, underspecified, allows code to pass your test that does things in a
// different order, where that different order should be considered wrong. Consider reading a
// file, where it needs to be first opened, then read and then closed.
//
// The default is to make tests overspecified. At least it prevents faulty code from passing
// unit tests. To locally disable (or enable) this behaviour, set the boolean autoExpect on your
// MockRepository to false (or true). To globally override, redefine DEFAULT_AUTOEXPECT to false.
#ifndef DEFAULT_AUTOEXPECT
#define DEFAULT_AUTOEXPECT true
#endif
#ifdef NO_HIPPOMOCKS_NAMESPACE
#define HM_NS
#else
#define HM_NS HippoMocks::
#endif
#ifdef _MSC_VER
#ifdef _WIN64
#define WINCALL
#else
#define WINCALL __stdcall
#endif
#endif
#ifndef DEBUGBREAK
#ifdef _MSC_VER
extern "C" __declspec(dllimport) int WINCALL IsDebuggerPresent();
extern "C" __declspec(dllimport) void WINCALL DebugBreak();
#define DEBUGBREAK(e) if (IsDebuggerPresent()) DebugBreak(); else (void)0
#else
#define DEBUGBREAK(e)
#endif
#endif
#ifndef DONTCARE_NAME
#define DONTCARE_NAME _
#endif
#ifndef VIRT_FUNC_LIMIT
#define VIRT_FUNC_LIMIT 1024
#elif VIRT_FUNC_LIMIT > 1024
#error Adjust the code to support more than 1024 virtual functions before setting the VIRT_FUNC_LIMIT above 1024
#endif
#ifdef __GNUC__
#define EXTRA_DESTRUCTOR
#endif
#ifdef __EDG__
#define FUNCTION_BASE 3
#define FUNCTION_STRIDE 2
#elif defined (__SUNPRO_CC) //Tested with SUN CC v12.1 on x86
#define FUNCTION_BASE 2
#define FUNCTION_STRIDE 1
#else
#define FUNCTION_BASE 0
#define FUNCTION_STRIDE 1
#endif
#if defined(_M_IX86) || defined(__i386__) || defined(i386) || defined(_X86_) || defined(__THW_INTEL) || defined(__x86_64__) || defined(_M_X64)
#define SOME_X86
#elif defined (sparc)
#elif defined(arm) || defined(__arm__) || defined(ARM) || defined(_ARM_) || defined(__aarch64__)
#define SOME_ARM
#endif
#if defined(__x86_64__) || defined(_M_X64)
#define CMOCK_FUNC_PLATFORMIS64BIT
#endif
#ifdef SOME_X86
#if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
#define _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
#elif (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__)
#define _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
#elif defined(__APPLE__)
#define _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
#endif
#elif defined(SOME_ARM) && defined(__GNUC__)
#define _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
// This clear-cache is *required*. The tests will fail if you remove it.
extern "C" void __clear_cache(void *beg, void *end);
#endif
#if defined(__GNUC__) && !defined(__EXCEPTIONS)
#define HM_NO_EXCEPTIONS
class X{};
#define BASE_EXCEPTION X
#else
#ifndef BASE_EXCEPTION
#define BASE_EXCEPTION std::exception
#include <exception>
#endif
#endif
#include <cstdio>
#include <list>
#include <map>
#include <memory>
#include <iostream>
#include <sstream>
#include <cstring>
#include <algorithm>
#include <limits>
#ifdef _MSC_VER
// these warnings are pointless and huge, and will confuse new users.
#pragma warning(push)
// If you can't generate an assignment operator the least you can do is shut up.
#pragma warning(disable: 4512)
// Alignment not right in a union?
#pragma warning(disable: 4121)
// No deprecated warnings on functions that really aren't deprecated at all.
#pragma warning(disable: 4996)
#endif
#ifndef NO_HIPPOMOCKS_NAMESPACE
namespace HippoMocks
{
#endif
//Type-safe exception wrapping
class ExceptionHolder
{
public:
virtual ~ExceptionHolder() {}
virtual void rethrow() = 0;
template <typename T>
static ExceptionHolder *Create(T ex);
};
template <class T>
class ExceptionWrapper : public ExceptionHolder {
T exception;
public:
ExceptionWrapper(T ex) : exception(ex) {}
void rethrow() { throw exception; }
};
template <typename T>
ExceptionHolder *ExceptionHolder::Create(T ex)
{
return new ExceptionWrapper<T>(ex);
}
#ifdef HM_NO_EXCEPTIONS
#define RAISEEXCEPTION(e) { std::string err = e.what(); DEBUGBREAK(e); printf("Mock error found - Fatal due to no exception support:\n"); \
printf("%s\n", err.c_str()); \
abort(); exit(-1); }
#define RAISELATENTEXCEPTION(e) { std::string err = e.what(); DEBUGBREAK(e); printf("Mock error found - Fatal due to no exception support:\n"); \
printf("%s\n", err.c_str()); \
abort(); exit(-1); }
#else
#define RAISEEXCEPTION(e) { DEBUGBREAK(e); throw e; }
#define RAISELATENTEXCEPTION(e) { DEBUGBREAK(e); if (std::uncaught_exception()) \
MockRepoInstanceHolder<0>::instance->SetLatentException(ExceptionHolder::Create(e)); \
else throw e; }
#endif
#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
#include <memory.h>
#if defined(_WIN32)
#ifndef NO_HIPPOMOCKS_NAMESPACE
}
#endif
// De-windows.h-ified import to avoid including that file.
#ifdef _WIN64
extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long long byteCount, unsigned long flags, unsigned long *oldFlags);
#else
extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long byteCount, unsigned long flags, unsigned long *oldFlags);
#endif
#ifndef PAGE_EXECUTE_READWRITE
#define PAGE_EXECUTE_READWRITE 0x40
#endif
#ifndef NO_HIPPOMOCKS_NAMESPACE
namespace HippoMocks {
#endif
class Unprotect
{
public:
Unprotect(void *location, size_t byteCount)
: origFunc(location)
, byteCount(byteCount)
{
VirtualProtect(origFunc, byteCount, PAGE_EXECUTE_READWRITE, &oldprotect);
}
~Unprotect()
{
unsigned long dontcare;
VirtualProtect(origFunc, byteCount, oldprotect, &dontcare);
}
private:
void *origFunc;
size_t byteCount;
unsigned long oldprotect;
};
#else
#include <sys/mman.h>
#include <stdint.h>
class Unprotect
{
public:
Unprotect(void *location, size_t count)
: origFunc((intptr_t)location & (~0xFFF))
, byteCount(count + ((intptr_t)location - origFunc))
{
mprotect((void *)origFunc, this->byteCount, PROT_READ|PROT_WRITE|PROT_EXEC);
};
~Unprotect()
{
mprotect((void *)origFunc, byteCount, PROT_READ|PROT_EXEC);
}
private:
intptr_t origFunc;
int byteCount;
};
#endif
typedef unsigned int e9ptrsize_t;
template <typename T, typename U>
T horrible_cast(U u)
{
union { T t; U u; } un;
un.u = u;
return un.t;
}
class Replace
{
private:
void *origFunc;
char backupData[16]; // typical use is 5 for 32-bit and 14 for 64-bit code.
public:
template <typename T>
Replace(T funcptr, T replacement)
: origFunc(horrible_cast<void *>(funcptr))
{
#ifdef SOME_X86
#ifdef CMOCK_FUNC_PLATFORMIS64BIT
if (llabs((long long)origFunc - (long long)replacement) < 0x80000000LL) {
#endif
Unprotect _allow_write(origFunc, sizeof(backupData));
memcpy(backupData, origFunc, sizeof(backupData));
*(unsigned char *)origFunc = 0xE9;
*(e9ptrsize_t*)(horrible_cast<intptr_t>(origFunc) + 1) = (e9ptrsize_t)(horrible_cast<intptr_t>(replacement) - horrible_cast<intptr_t>(origFunc) - sizeof(e9ptrsize_t) - 1);
#ifdef CMOCK_FUNC_PLATFORMIS64BIT
} else {
if (*(unsigned char *)origFunc == 0xE9) {
// If this is a jmp instruction (rip + 32-bit signed) then most likely this is a entry into the import table,
// overwriting it will corrupt the next entry in the table, we need to find the real address and replace the content in there.
unsigned char *pFunc = (unsigned char *)origFunc;
pFunc += *(e9ptrsize_t*)(pFunc + 1) + sizeof(e9ptrsize_t) + 1;
origFunc = horrible_cast<void *>(pFunc);
}
Unprotect _allow_write(origFunc, sizeof(backupData));
memcpy(backupData, origFunc, sizeof(backupData));
unsigned char *func = (unsigned char *)origFunc;
func[0] = 0xFF; // jmp (rip + imm32)
func[1] = 0x25;
func[2] = 0x00; // imm32 of 0, so immediately after the instruction
func[3] = 0x00;
func[4] = 0x00;
func[5] = 0x00;
*(long long*)(horrible_cast<intptr_t>(origFunc) + 6) = (long long)(horrible_cast<intptr_t>(replacement));
}
#endif
#elif defined(SOME_ARM)
Unprotect _allow_write(origFunc, sizeof(backupData));
memcpy(backupData, origFunc, sizeof(backupData));
unsigned int *rawptr = (unsigned int *)((intptr_t)(origFunc) & (~3));
if ((intptr_t)origFunc & 1) {
rawptr[0] = 0x6800A001;
rawptr[1] = 0x46874687;
rawptr[2] = (intptr_t)replacement;
} else {
rawptr[0] = 0xE59FF000;
rawptr[1] = (intptr_t)replacement;
rawptr[2] = (intptr_t)replacement;
}
__clear_cache((char *)rawptr, (char *)rawptr+16);
#endif
}
~Replace()
{
Unprotect _allow_write(origFunc, sizeof(backupData));
memcpy(origFunc, backupData, sizeof(backupData));
#ifdef SOME_ARM
unsigned int *rawptr = (unsigned int *)((intptr_t)(origFunc) & (~3));
__clear_cache((char *)rawptr, (char *)rawptr+16);
#endif
}
};
#endif
class MockRepository;
struct
RegistrationType
{
RegistrationType( unsigned min, unsigned max ) : minimum( min ), maximum( max ) {}
unsigned minimum;
unsigned maximum;
};
inline
bool operator==( RegistrationType const& rhs, RegistrationType const& lhs )
{
return rhs.minimum == lhs.minimum && rhs.maximum == lhs.maximum;
}
const RegistrationType Any = RegistrationType((std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::max)());
const RegistrationType Never = RegistrationType((std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)());
const RegistrationType Once = RegistrationType( 1, 1 );
// base type
class base_mock {
public:
void destroy() { unwriteVft(); delete this; }
virtual ~base_mock() {}
void *rewriteVft(void *newVf)
{
void *oldVf = *(void **)this;
*(void **)this = newVf;
return oldVf;
}
void reset()
{
unwriteVft();
mock_reset();
}
virtual void mock_reset() = 0;
void unwriteVft()
{
*(void **)this = (*(void ***)this)[VIRT_FUNC_LIMIT+1];
}
};
template <typename T>
class ByRef
{
public:
explicit ByRef(T &argument) : arg(argument) {}
void operator()() { arg(); }
T &arg;
};
template <typename T>
ByRef<T> byRef(T &arg) {
return ByRef<T>(arg);
}
class NullType
{
public:
bool operator==(const NullType &) const
{
return true;
}
};
class DontCare {
private:
inline DontCare &Instance();
};
static DontCare DONTCARE_NAME;
inline DontCare &DontCare::Instance()
{
return DONTCARE_NAME;
}
template <typename T>
struct OutParam: public DontCare
{
explicit OutParam(T val): value(val) {}
T value;
};
template <typename T>
OutParam<T> Out(T t) { return OutParam<T>(t); }
template <typename T, bool isPointer>
struct InParam;
template <typename T>
struct InParam<T, false>: public DontCare
{
explicit InParam(T& val): value(val)
{
}
T& value;
};
template <typename T>
struct InParam<T, true>: public DontCare
{
explicit InParam(T*& val): value(val)
{
}
T*& value;
};
template <typename T>
InParam<T, false> In(T& t) { return InParam<T, false>(t); }
template <typename T>
InParam<T, true> In(T*& t) { return InParam<T, true>(t); }
struct NotPrintable { template <typename T> NotPrintable(T const&) {} };
inline std::ostream &operator<<(std::ostream &os, NotPrintable const&)
{
os << "???";
return os;
}
inline std::ostream &operator<<(std::ostream &os, DontCare const&)
{
os << "_";
return os;
}
template <typename T>
inline std::ostream &operator<<(std::ostream &os, ByRef<T> &ref) {
os << "byRef(" << (T)ref << ")";
return os;
}
template <typename T>
struct printArg
{
static inline void print(std::ostream &os, T arg, bool withComma)
{
if (withComma)
os << ",";
os << arg;
}
};
template <>
struct printArg<NullType>
{
static void print(std::ostream &, NullType , bool)
{
}
};
class base_tuple
{
protected:
base_tuple()
{
}
public:
virtual ~base_tuple()
{
}
virtual void printTo(std::ostream &os) const = 0;
};
template <typename X>
struct no_cref { typedef X type; };
template <typename X>
struct no_cref<const X &> { typedef X type; };
template <typename A> struct with_const { typedef const A type; };
template <typename A> struct with_const<A &> { typedef const A &type; };
template <typename A> struct with_const<const A> { typedef const A type; };
template <typename A> struct with_const<const A &> { typedef const A &type; };
template <typename T> struct base_type { typedef T type; };
template <typename T> struct base_type<T&> { typedef T type; };
template <typename T> struct base_type<const T> { typedef T type; };
template <typename T> struct base_type<const T&> { typedef T type; };
template <typename T>
struct comparer
{
static inline bool compare(typename with_const<T>::type a, typename with_const<T>::type b)
{
return a == b;
}
static inline bool compare(DontCare, typename with_const<T>::type)
{
return true;
}
template <typename U>
static inline bool compare(const ByRef<U> &a, typename with_const<T>::type b)
{
return &a.arg == &b;
}
};
template <typename T>
struct IsOutParamType { enum { value = false }; };
template <typename T>
struct IsOutParamType<OutParam<T> > { enum { value = true }; };
template <typename T>
struct IsInParamType { enum { value = false }; };
template <typename T>
struct IsInParamType<InParam<T, true> > { enum { value = true }; };
template <typename T>
struct IsInParamType<InParam<T, false> > { enum { value = true }; };
template <typename T1, typename T2, bool Assign>
struct do_assign;
template <typename T1, typename T2>
struct do_assign<T1, T2*, true>
{
static void assign_to(T1 outparam, T2 *refparam)
{
*refparam = outparam.value;
}
static void assign_from(T1 inparam, T2 *refparam)
{
inparam.value = refparam;
}
};
template <typename T1, typename T2>
struct do_assign<T1, T2&, true>
{
static void assign_to(T1 outparam, T2 &refparam)
{
refparam = outparam.value;
}
static void assign_from(T1 inparam, T2 &refparam)
{
inparam.value = refparam;
}
};
template <typename T1, typename T2>
struct do_assign<T1, T2, false>
{
static void assign_to(T1, T2) {}
static void assign_from(T1, T2) {}
};
template <typename T1, typename T2>
void out_assign(T1 a, T2 b)
{
do_assign<T1, T2, IsOutParamType<typename base_type<T1>::type>::value >::assign_to(a, b);
}
template <typename T1, typename T2>
void in_assign(T1 a, T2 b)
{
do_assign<T1, T2, IsInParamType<typename base_type<T1>::type>::value >::assign_from(a, b);
}
template <typename A = NullType, typename B = NullType, typename C = NullType, typename D = NullType,
typename E = NullType, typename F = NullType, typename G = NullType, typename H = NullType,
typename I = NullType, typename J = NullType, typename K = NullType, typename L = NullType,
typename M = NullType, typename N = NullType, typename O = NullType, typename P = NullType>
class ref_tuple : public base_tuple
{
public:
A a;
B b;
C c;
D d;
E e;
F f;
G g;
H h;
I i;
J j;
K k;
L l;
M m;
N n;
O o;
P p;
ref_tuple(A valueA = A(), B valueB = B(), C valueC = C(), D valueD = D(), E valueE = E(), F valueF = F(), G valueG = G(), H valueH = H(), I valueI = I(), J valueJ = J(), K valueK = K(), L valueL = L(), M valueM = M(), N valueN = N(), O valueO = O(), P valueP = P())
: a(valueA), b(valueB), c(valueC), d(valueD), e(valueE), f(valueF), g(valueG), h(valueH), i(valueI), j(valueJ), k(valueK), l(valueL), m(valueM), n(valueN), o(valueO), p(valueP)
{}
virtual void printTo(std::ostream &os) const
{
os << "(";
printArg<A>::print(os, a, false);
printArg<B>::print(os, b, true);
printArg<C>::print(os, c, true);
printArg<D>::print(os, d, true);
printArg<E>::print(os, e, true);
printArg<F>::print(os, f, true);
printArg<G>::print(os, g, true);
printArg<H>::print(os, h, true);
printArg<I>::print(os, i, true);
printArg<J>::print(os, j, true);
printArg<K>::print(os, k, true);
printArg<L>::print(os, l, true);
printArg<M>::print(os, m, true);
printArg<N>::print(os, n, true);
printArg<O>::print(os, o, true);
printArg<P>::print(os, p, true);
os << ")";
}
};
template <typename A = NullType, typename B = NullType, typename C = NullType, typename D = NullType,
typename E = NullType, typename F = NullType, typename G = NullType, typename H = NullType,
typename I = NullType, typename J = NullType, typename K = NullType, typename L = NullType,
typename M = NullType, typename N = NullType, typename O = NullType, typename P = NullType>
class ref_comparable_assignable_tuple : public base_tuple
{
public:
virtual bool operator==(const ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &bo) = 0;
virtual void assign_from(ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &from) = 0;
virtual void assign_to(ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &to) = 0;
};
template <typename T> struct no_array { typedef T type; };
template <typename T, int N> struct no_array<T[N]> { typedef T* type; };
template <typename B>
struct store_as
{
typedef typename no_array<B>::type type;
};
template <typename B>
struct store_as<B&>
{
typedef typename no_array<B>::type type;
};
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H,
typename I, typename J, typename K, typename L, typename M, typename N, typename O, typename P,
typename CA, typename CB, typename CC, typename CD, typename CE, typename CF, typename CG, typename CH,
typename CI, typename CJ, typename CK, typename CL, typename CM, typename CN, typename CO, typename CP>
class copy_tuple : public ref_comparable_assignable_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P>
{
public:
typename store_as<CA>::type a;
typename store_as<CB>::type b;
typename store_as<CC>::type c;
typename store_as<CD>::type d;
typename store_as<CE>::type e;
typename store_as<CF>::type f;
typename store_as<CG>::type g;
typename store_as<CH>::type h;
typename store_as<CI>::type i;
typename store_as<CJ>::type j;
typename store_as<CK>::type k;
typename store_as<CL>::type l;
typename store_as<CM>::type m;
typename store_as<CN>::type n;
typename store_as<CO>::type o;
typename store_as<CP>::type p;
copy_tuple(typename store_as<CA>::type valueA, typename store_as<CB>::type valueB,
typename store_as<CC>::type valueC, typename store_as<CD>::type valueD,
typename store_as<CE>::type valueE, typename store_as<CF>::type valueF,
typename store_as<CG>::type valueG, typename store_as<CH>::type valueH,
typename store_as<CI>::type valueI, typename store_as<CJ>::type valueJ,
typename store_as<CK>::type valueK, typename store_as<CL>::type valueL,
typename store_as<CM>::type valueM, typename store_as<CN>::type valueN,
typename store_as<CO>::type valueO, typename store_as<CP>::type valueP)
: a(valueA), b(valueB), c(valueC), d(valueD), e(valueE), f(valueF), g(valueG), h(valueH), i(valueI), j(valueJ), k(valueK), l(valueL), m(valueM), n(valueN), o(valueO), p(valueP)
{}
bool operator==(const ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &to)
{
return (comparer<A>::compare(a, to.a) &&
comparer<B>::compare(b, to.b) &&
comparer<C>::compare(c, to.c) &&
comparer<D>::compare(d, to.d) &&
comparer<E>::compare(e, to.e) &&
comparer<F>::compare(f, to.f) &&
comparer<G>::compare(g, to.g) &&
comparer<H>::compare(h, to.h) &&
comparer<I>::compare(i, to.i) &&
comparer<J>::compare(j, to.j) &&
comparer<K>::compare(k, to.k) &&
comparer<L>::compare(l, to.l) &&
comparer<M>::compare(m, to.m) &&
comparer<N>::compare(n, to.n) &&
comparer<O>::compare(o, to.o) &&
comparer<P>::compare(p, to.p));
}
void assign_from(ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &from)
{
in_assign< typename store_as<CA>::type, A>(a, from.a);
in_assign< typename store_as<CB>::type, B>(b, from.b);
in_assign< typename store_as<CC>::type, C>(c, from.c);
in_assign< typename store_as<CD>::type, D>(d, from.d);
in_assign< typename store_as<CE>::type, E>(e, from.e);
in_assign< typename store_as<CF>::type, F>(f, from.f);
in_assign< typename store_as<CG>::type, G>(g, from.g);
in_assign< typename store_as<CH>::type, H>(h, from.h);
in_assign< typename store_as<CI>::type, I>(i, from.i);
in_assign< typename store_as<CJ>::type, J>(j, from.j);
in_assign< typename store_as<CK>::type, K>(k, from.k);
in_assign< typename store_as<CL>::type, L>(l, from.l);
in_assign< typename store_as<CM>::type, M>(m, from.m);
in_assign< typename store_as<CN>::type, N>(n, from.n);
in_assign< typename store_as<CO>::type, O>(o, from.o);
in_assign< typename store_as<CP>::type, P>(p, from.p);
}
void assign_to(ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &to)
{
out_assign< typename store_as<CA>::type, A>(a, to.a);
out_assign< typename store_as<CB>::type, B>(b, to.b);
out_assign< typename store_as<CC>::type, C>(c, to.c);
out_assign< typename store_as<CD>::type, D>(d, to.d);
out_assign< typename store_as<CE>::type, E>(e, to.e);
out_assign< typename store_as<CF>::type, F>(f, to.f);
out_assign< typename store_as<CG>::type, G>(g, to.g);
out_assign< typename store_as<CH>::type, H>(h, to.h);
out_assign< typename store_as<CI>::type, I>(i, to.i);
out_assign< typename store_as<CJ>::type, J>(j, to.j);
out_assign< typename store_as<CK>::type, K>(k, to.k);
out_assign< typename store_as<CL>::type, L>(l, to.l);
out_assign< typename store_as<CM>::type, M>(m, to.m);
out_assign< typename store_as<CN>::type, N>(n, to.n);
out_assign< typename store_as<CO>::type, O>(o, to.o);
out_assign< typename store_as<CP>::type, P>(p, to.p);
}
virtual void printTo(std::ostream &os) const
{
os << "(";
printArg<typename store_as<CA>::type>::print(os, a, false);
printArg<typename store_as<CB>::type>::print(os, b, true);
printArg<typename store_as<CC>::type>::print(os, c, true);
printArg<typename store_as<CD>::type>::print(os, d, true);
printArg<typename store_as<CE>::type>::print(os, e, true);
printArg<typename store_as<CF>::type>::print(os, f, true);
printArg<typename store_as<CG>::type>::print(os, g, true);
printArg<typename store_as<CH>::type>::print(os, h, true);
printArg<typename store_as<CI>::type>::print(os, i, true);
printArg<typename store_as<CJ>::type>::print(os, j, true);
printArg<typename store_as<CK>::type>::print(os, k, true);
printArg<typename store_as<CL>::type>::print(os, l, true);
printArg<typename store_as<CM>::type>::print(os, m, true);
printArg<typename store_as<CN>::type>::print(os, n, true);
printArg<typename store_as<CO>::type>::print(os, o, true);
printArg<typename store_as<CP>::type>::print(os, p, true);
os << ")";
}
};
inline std::ostream &operator<<(std::ostream &os, const MockRepository &repo);
template <int X>
class MockRepoInstanceHolder {
public:
static MockRepository *instance;
};
template <int X>
MockRepository *MockRepoInstanceHolder<X>::instance;
class BaseException
#ifndef HM_NO_EXCEPTIONS
: public BASE_EXCEPTION
#endif
{
public:
~BaseException() throw() {}
const char *what() const throw() { return txt.c_str(); }
protected:
std::string txt;
};
// exception types
class ExpectationException : public BaseException {
public:
ExpectationException(MockRepository *repo, const base_tuple *tuple, const char *funcName)
{
std::stringstream text;
text << "Function ";
text << funcName;
if (tuple)
tuple->printTo(text);
else
text << "(...)";
text << " called with mismatching expectation!" << std::endl;
text << *repo;
txt = text.str();
}
};
#ifdef LINUX_TARGET
#include <execinfo.h>
#endif
class NotImplementedException : public BaseException {
public:
NotImplementedException(MockRepository *repo)
{
std::stringstream text;
text << "Function called without expectation!" << std::endl;
text << *repo;
#ifdef LINUX_TARGET
void* stacktrace[256];
size_t size = backtrace( stacktrace, sizeof(stacktrace) );
if( size > 0 )
{
text << "Stackdump:" << std::endl;
char **symbols = backtrace_symbols( stacktrace, size );
for( size_t i = 0; i < size; i = i + 1 )
{
text << symbols[i] << std::endl;
}
free( symbols );
}
#endif
txt = text.str();
}
};
class CallMissingException : public BaseException {
public:
CallMissingException(MockRepository *repo)
{
std::stringstream text;
text << "Function with expectation not called!" << std::endl;
text << *repo;
txt = text.str();
}
};
class ZombieMockException : public BaseException {
public:
ZombieMockException(MockRepository *repo)
{
std::stringstream text;
text << "Function called on mock that has already been destroyed!" << std::endl;
text << *repo;
#ifdef LINUX_TARGET
void* stacktrace[256];
size_t size = backtrace( stacktrace, sizeof(stacktrace) );
if( size > 0 )
{
text << "Stackdump:" << std::endl;
char **symbols = backtrace_symbols( stacktrace, size );
for( size_t i = 0; i < size; i = i + 1 )
{
text << symbols[i] << std::endl;
}
free( symbols );
}
#endif
txt = text.str();
}
};
class NoResultSetUpException : public BaseException {
public:
NoResultSetUpException(MockRepository *repo, const base_tuple *tuple, const char *funcName)
{
std::stringstream text;
text << "No result set up on call to ";
text << funcName;
if (tuple)
tuple->printTo(text);
else
text << "(...)";
text << std::endl;
text << *repo;
#ifdef LINUX_TARGET
void* stacktrace[256];
size_t size = backtrace( stacktrace, sizeof(stacktrace) );
if( size > 0 )
{
text << "Stackdump:" << std::endl;
char **symbols = backtrace_symbols( stacktrace, size );
for( size_t i = 0; i < size; i = i + 1 )
{
text << symbols[i] << std::endl;
}
free( symbols );
}
#endif
txt = text.str();
}
};
// function-index-of-type
class func_index {
public:
int lci;
virtual int f0(int) { return lci=0; } virtual int f1(int) { return lci=1; } virtual int f2(int) { return lci=2; } virtual int f3(int) { return lci=3; }
virtual int f4(int) { return lci=4; } virtual int f5(int) { return lci=5; } virtual int f6(int) { return lci=6; } virtual int f7(int) { return lci=7; }
virtual int f8(int) { return lci=8; } virtual int f9(int) { return lci=9; } virtual int f10(int) { return lci=10; } virtual int f11(int) { return lci=11; }
virtual int f12(int) { return lci=12; } virtual int f13(int) { return lci=13; } virtual int f14(int) { return lci=14; } virtual int f15(int) { return lci=15; }
virtual int f16(int) { return lci=16; } virtual int f17(int) { return lci=17; } virtual int f18(int) { return lci=18; } virtual int f19(int) { return lci=19; }
virtual int f20(int) { return lci=20; } virtual int f21(int) { return lci=21; } virtual int f22(int) { return lci=22; } virtual int f23(int) { return lci=23; }
virtual int f24(int) { return lci=24; } virtual int f25(int) { return lci=25; } virtual int f26(int) { return lci=26; } virtual int f27(int) { return lci=27; }
virtual int f28(int) { return lci=28; } virtual int f29(int) { return lci=29; } virtual int f30(int) { return lci=30; } virtual int f31(int) { return lci=31; }
virtual int f32(int) { return lci=32; } virtual int f33(int) { return lci=33; } virtual int f34(int) { return lci=34; } virtual int f35(int) { return lci=35; }
virtual int f36(int) { return lci=36; } virtual int f37(int) { return lci=37; } virtual int f38(int) { return lci=38; } virtual int f39(int) { return lci=39; }
virtual int f40(int) { return lci=40; } virtual int f41(int) { return lci=41; } virtual int f42(int) { return lci=42; } virtual int f43(int) { return lci=43; }
virtual int f44(int) { return lci=44; } virtual int f45(int) { return lci=45; } virtual int f46(int) { return lci=46; } virtual int f47(int) { return lci=47; }
virtual int f48(int) { return lci=48; } virtual int f49(int) { return lci=49; } virtual int f50(int) { return lci=50; } virtual int f51(int) { return lci=51; }
virtual int f52(int) { return lci=52; } virtual int f53(int) { return lci=53; } virtual int f54(int) { return lci=54; } virtual int f55(int) { return lci=55; }
virtual int f56(int) { return lci=56; } virtual int f57(int) { return lci=57; } virtual int f58(int) { return lci=58; } virtual int f59(int) { return lci=59; }
virtual int f60(int) { return lci=60; } virtual int f61(int) { return lci=61; } virtual int f62(int) { return lci=62; } virtual int f63(int) { return lci=63; }
virtual int f64(int) { return lci=64; } virtual int f65(int) { return lci=65; } virtual int f66(int) { return lci=66; } virtual int f67(int) { return lci=67; }
virtual int f68(int) { return lci=68; } virtual int f69(int) { return lci=69; } virtual int f70(int) { return lci=70; } virtual int f71(int) { return lci=71; }
virtual int f72(int) { return lci=72; } virtual int f73(int) { return lci=73; } virtual int f74(int) { return lci=74; } virtual int f75(int) { return lci=75; }
virtual int f76(int) { return lci=76; } virtual int f77(int) { return lci=77; } virtual int f78(int) { return lci=78; } virtual int f79(int) { return lci=79; }
virtual int f80(int) { return lci=80; } virtual int f81(int) { return lci=81; } virtual int f82(int) { return lci=82; } virtual int f83(int) { return lci=83; }
virtual int f84(int) { return lci=84; } virtual int f85(int) { return lci=85; } virtual int f86(int) { return lci=86; } virtual int f87(int) { return lci=87; }
virtual int f88(int) { return lci=88; } virtual int f89(int) { return lci=89; } virtual int f90(int) { return lci=90; } virtual int f91(int) { return lci=91; }
virtual int f92(int) { return lci=92; } virtual int f93(int) { return lci=93; } virtual int f94(int) { return lci=94; } virtual int f95(int) { return lci=95; }
virtual int f96(int) { return lci=96; } virtual int f97(int) { return lci=97; } virtual int f98(int) { return lci=98; } virtual int f99(int) { return lci=99; }
virtual int f100(int) { return lci=100; } virtual int f101(int) { return lci=101; } virtual int f102(int) { return lci=102; } virtual int f103(int) { return lci=103; }
virtual int f104(int) { return lci=104; } virtual int f105(int) { return lci=105; } virtual int f106(int) { return lci=106; } virtual int f107(int) { return lci=107; }
virtual int f108(int) { return lci=108; } virtual int f109(int) { return lci=109; } virtual int f110(int) { return lci=110; } virtual int f111(int) { return lci=111; }
virtual int f112(int) { return lci=112; } virtual int f113(int) { return lci=113; } virtual int f114(int) { return lci=114; } virtual int f115(int) { return lci=115; }
virtual int f116(int) { return lci=116; } virtual int f117(int) { return lci=117; } virtual int f118(int) { return lci=118; } virtual int f119(int) { return lci=119; }
virtual int f120(int) { return lci=120; } virtual int f121(int) { return lci=121; } virtual int f122(int) { return lci=122; } virtual int f123(int) { return lci=123; }
virtual int f124(int) { return lci=124; } virtual int f125(int) { return lci=125; } virtual int f126(int) { return lci=126; } virtual int f127(int) { return lci=127; }
virtual int f128(int) { return lci=128; } virtual int f129(int) { return lci=129; } virtual int f130(int) { return lci=130; } virtual int f131(int) { return lci=131; }
virtual int f132(int) { return lci=132; } virtual int f133(int) { return lci=133; } virtual int f134(int) { return lci=134; } virtual int f135(int) { return lci=135; }
virtual int f136(int) { return lci=136; } virtual int f137(int) { return lci=137; } virtual int f138(int) { return lci=138; } virtual int f139(int) { return lci=139; }
virtual int f140(int) { return lci=140; } virtual int f141(int) { return lci=141; } virtual int f142(int) { return lci=142; } virtual int f143(int) { return lci=143; }
virtual int f144(int) { return lci=144; } virtual int f145(int) { return lci=145; } virtual int f146(int) { return lci=146; } virtual int f147(int) { return lci=147; }
virtual int f148(int) { return lci=148; } virtual int f149(int) { return lci=149; } virtual int f150(int) { return lci=150; } virtual int f151(int) { return lci=151; }
virtual int f152(int) { return lci=152; } virtual int f153(int) { return lci=153; } virtual int f154(int) { return lci=154; } virtual int f155(int) { return lci=155; }
virtual int f156(int) { return lci=156; } virtual int f157(int) { return lci=157; } virtual int f158(int) { return lci=158; } virtual int f159(int) { return lci=159; }
virtual int f160(int) { return lci=160; } virtual int f161(int) { return lci=161; } virtual int f162(int) { return lci=162; } virtual int f163(int) { return lci=163; }
virtual int f164(int) { return lci=164; } virtual int f165(int) { return lci=165; } virtual int f166(int) { return lci=166; } virtual int f167(int) { return lci=167; }
virtual int f168(int) { return lci=168; } virtual int f169(int) { return lci=169; } virtual int f170(int) { return lci=170; } virtual int f171(int) { return lci=171; }
virtual int f172(int) { return lci=172; } virtual int f173(int) { return lci=173; } virtual int f174(int) { return lci=174; } virtual int f175(int) { return lci=175; }
virtual int f176(int) { return lci=176; } virtual int f177(int) { return lci=177; } virtual int f178(int) { return lci=178; } virtual int f179(int) { return lci=179; }
virtual int f180(int) { return lci=180; } virtual int f181(int) { return lci=181; } virtual int f182(int) { return lci=182; } virtual int f183(int) { return lci=183; }
virtual int f184(int) { return lci=184; } virtual int f185(int) { return lci=185; } virtual int f186(int) { return lci=186; } virtual int f187(int) { return lci=187; }
virtual int f188(int) { return lci=188; } virtual int f189(int) { return lci=189; } virtual int f190(int) { return lci=190; } virtual int f191(int) { return lci=191; }
virtual int f192(int) { return lci=192; } virtual int f193(int) { return lci=193; } virtual int f194(int) { return lci=194; } virtual int f195(int) { return lci=195; }
virtual int f196(int) { return lci=196; } virtual int f197(int) { return lci=197; } virtual int f198(int) { return lci=198; } virtual int f199(int) { return lci=199; }
virtual int f200(int) { return lci=200; } virtual int f201(int) { return lci=201; } virtual int f202(int) { return lci=202; } virtual int f203(int) { return lci=203; }
virtual int f204(int) { return lci=204; } virtual int f205(int) { return lci=205; } virtual int f206(int) { return lci=206; } virtual int f207(int) { return lci=207; }
virtual int f208(int) { return lci=208; } virtual int f209(int) { return lci=209; } virtual int f210(int) { return lci=210; } virtual int f211(int) { return lci=211; }
virtual int f212(int) { return lci=212; } virtual int f213(int) { return lci=213; } virtual int f214(int) { return lci=214; } virtual int f215(int) { return lci=215; }
virtual int f216(int) { return lci=216; } virtual int f217(int) { return lci=217; } virtual int f218(int) { return lci=218; } virtual int f219(int) { return lci=219; }
virtual int f220(int) { return lci=220; } virtual int f221(int) { return lci=221; } virtual int f222(int) { return lci=222; } virtual int f223(int) { return lci=223; }
virtual int f224(int) { return lci=224; } virtual int f225(int) { return lci=225; } virtual int f226(int) { return lci=226; } virtual int f227(int) { return lci=227; }
virtual int f228(int) { return lci=228; } virtual int f229(int) { return lci=229; } virtual int f230(int) { return lci=230; } virtual int f231(int) { return lci=231; }
virtual int f232(int) { return lci=232; } virtual int f233(int) { return lci=233; } virtual int f234(int) { return lci=234; } virtual int f235(int) { return lci=235; }
virtual int f236(int) { return lci=236; } virtual int f237(int) { return lci=237; } virtual int f238(int) { return lci=238; } virtual int f239(int) { return lci=239; }
virtual int f240(int) { return lci=240; } virtual int f241(int) { return lci=241; } virtual int f242(int) { return lci=242; } virtual int f243(int) { return lci=243; }
virtual int f244(int) { return lci=244; } virtual int f245(int) { return lci=245; } virtual int f246(int) { return lci=246; } virtual int f247(int) { return lci=247; }
virtual int f248(int) { return lci=248; } virtual int f249(int) { return lci=249; } virtual int f250(int) { return lci=250; } virtual int f251(int) { return lci=251; }
virtual int f252(int) { return lci=252; } virtual int f253(int) { return lci=253; } virtual int f254(int) { return lci=254; } virtual int f255(int) { return lci=255; }
virtual int f256(int) { return lci=256; } virtual int f257(int) { return lci=257; } virtual int f258(int) { return lci=258; } virtual int f259(int) { return lci=259; }