mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-04 03:11:43 +00:00
Compare commits
419 Commits
v2017.1.1-
...
v2018.2.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02336fc478 | ||
|
|
c00848c060 | ||
|
|
738a1c015c | ||
|
|
48ae6c954a | ||
|
|
07f70cf784 | ||
|
|
e4e1eab413 | ||
|
|
0e8ff4663d | ||
|
|
54a0a7654a | ||
|
|
59f938b584 | ||
|
|
5513888457 | ||
|
|
02b6615042 | ||
|
|
1f4822f332 | ||
|
|
bb38ef5642 | ||
|
|
ca36d1dce6 | ||
|
|
ee33296e1f | ||
|
|
0ef9803363 | ||
|
|
eedb8910c3 | ||
|
|
8346caed9c | ||
|
|
55b6764d50 | ||
|
|
2c4faee667 | ||
|
|
8d1dee16be | ||
|
|
76b182600a | ||
|
|
c647a801ad | ||
|
|
02131639bc | ||
|
|
566e283694 | ||
|
|
40eb6dfc9b | ||
|
|
a3e5378d14 | ||
|
|
691741cfcb | ||
|
|
166d9e01bf | ||
|
|
7eab4371f4 | ||
|
|
de134a5c60 | ||
|
|
7f074563d0 | ||
|
|
d3dd586362 | ||
|
|
9c85105591 | ||
|
|
86ac70a125 | ||
|
|
3c3a448d47 | ||
|
|
8744511f1d | ||
|
|
7729dd972f | ||
|
|
8b7aa61091 | ||
|
|
88a6b4ac38 | ||
|
|
217b1a2259 | ||
|
|
d2e7a90f41 | ||
|
|
8bd48d6c34 | ||
|
|
1fa0adb091 | ||
|
|
f615e68a43 | ||
|
|
aa4f0ef4f8 | ||
|
|
b42285fddd | ||
|
|
8106fbdbea | ||
|
|
942ba51765 | ||
|
|
33a08d5b34 | ||
|
|
4e3af0756d | ||
|
|
5078f6c92a | ||
|
|
899892c119 | ||
|
|
54326311ad | ||
|
|
fe53dd2f28 | ||
|
|
ab137abab5 | ||
|
|
001dedf3b2 | ||
|
|
f9bece2ffb | ||
|
|
3befc7015b | ||
|
|
de63e1c8a1 | ||
|
|
a76b1aa800 | ||
|
|
350b741adc | ||
|
|
64bfdc1a69 | ||
|
|
65cc85f68d | ||
|
|
6a00dc7976 | ||
|
|
e9e407a87d | ||
|
|
59c4984ed6 | ||
|
|
b428d1e4b3 | ||
|
|
0994364591 | ||
|
|
0b8d3f0260 | ||
|
|
52eba45c51 | ||
|
|
9090a82ef5 | ||
|
|
2a69a4c7dc | ||
|
|
9d2393f97e | ||
|
|
dae619b006 | ||
|
|
9c06d2878b | ||
|
|
e3a2abdf97 | ||
|
|
7867e906e9 | ||
|
|
65a044f633 | ||
|
|
cbd08a1e11 | ||
|
|
e308dd28f3 | ||
|
|
fa0b4428e9 | ||
|
|
26a36779a6 | ||
|
|
dfc0656e5c | ||
|
|
0f3f5218ad | ||
|
|
34c44b7ae9 | ||
|
|
7a250a1b93 | ||
|
|
a338ee8be0 | ||
|
|
c9d440f338 | ||
|
|
a00b2449db | ||
|
|
5c659fdcdf | ||
|
|
d36d72bd4f | ||
|
|
614093c0c4 | ||
|
|
12c4418bda | ||
|
|
0431cf97ff | ||
|
|
ba879f4663 | ||
|
|
96de0b5b11 | ||
|
|
85157a56c3 | ||
|
|
029246ed28 | ||
|
|
6377ab774d | ||
|
|
05e581f409 | ||
|
|
c73dd807e1 | ||
|
|
7a0dd9baa9 | ||
|
|
11f37683c3 | ||
|
|
5af0c9c101 | ||
|
|
259461aee9 | ||
|
|
d214b36786 | ||
|
|
4a07f0380f | ||
|
|
7f46b50b21 | ||
|
|
303c259b89 | ||
|
|
cd1dbb1e3a | ||
|
|
a20474bfc7 | ||
|
|
479d0beb5a | ||
|
|
b93aa176d6 | ||
|
|
9021b37fd2 | ||
|
|
6307d41002 | ||
|
|
df7c1389de | ||
|
|
6accc31ee7 | ||
|
|
f56ec10bcf | ||
|
|
e5e6d6a193 | ||
|
|
c663d7cd16 | ||
|
|
1e8d18b328 | ||
|
|
c2d95db3ab | ||
|
|
dd7563376b | ||
|
|
14fcf3f2f0 | ||
|
|
020ee227d2 | ||
|
|
4d559f3856 | ||
|
|
35d68d2a34 | ||
|
|
7007725d9f | ||
|
|
0c83cad70c | ||
|
|
0001047b8b | ||
|
|
c885251367 | ||
|
|
42096fac3f | ||
|
|
6be9e69d13 | ||
|
|
7bbd13d914 | ||
|
|
2225c4fee2 | ||
|
|
7efab4c43a | ||
|
|
c8e44256ef | ||
|
|
f3cd883c5c | ||
|
|
f34c736fb2 | ||
|
|
1276489961 | ||
|
|
8b2e656bde | ||
|
|
6e9d1f55c6 | ||
|
|
f4dce9e608 | ||
|
|
b9aabc71b0 | ||
|
|
0d54772362 | ||
|
|
faf134a674 | ||
|
|
c24e755409 | ||
|
|
bee9f1cb17 | ||
|
|
45d48d6b5a | ||
|
|
6401aa1fde | ||
|
|
6af4940c22 | ||
|
|
237b2df82f | ||
|
|
a70687aaec | ||
|
|
fbfe85568b | ||
|
|
595b1df380 | ||
|
|
efc7770e9b | ||
|
|
21585f70a8 | ||
|
|
c33fca34e9 | ||
|
|
de95f08a10 | ||
|
|
90f99dc571 | ||
|
|
f34332643a | ||
|
|
4ab095e9c9 | ||
|
|
541753c814 | ||
|
|
f02bb058bd | ||
|
|
12e96c6f13 | ||
|
|
b65447b6f5 | ||
|
|
9945a5b3c6 | ||
|
|
ce4c9edd1f | ||
|
|
a6e6ae41b9 | ||
|
|
f4e2e41aaf | ||
|
|
1e528669ff | ||
|
|
a1ea448406 | ||
|
|
9dc1de1d09 | ||
|
|
0521d85048 | ||
|
|
3c842d8234 | ||
|
|
be77f9cb26 | ||
|
|
2fc60680f4 | ||
|
|
0291a95f68 | ||
|
|
66002d6cac | ||
|
|
a7e9ac1062 | ||
|
|
434d60592c | ||
|
|
ee20747255 | ||
|
|
f4779379c3 | ||
|
|
877a9eae1f | ||
|
|
24752a9751 | ||
|
|
e1dc099517 | ||
|
|
f0cc623241 | ||
|
|
ba3a85d0cc | ||
|
|
79919a5f1c | ||
|
|
94ea5bfb06 | ||
|
|
24680bbd53 | ||
|
|
7fab0e0ef2 | ||
|
|
dd66b23845 | ||
|
|
19addb04cf | ||
|
|
abb66d3e4b | ||
|
|
db4981f166 | ||
|
|
6e1be897de | ||
|
|
423d8f6860 | ||
|
|
eb38204d1a | ||
|
|
1711291cd8 | ||
|
|
57ba58917d | ||
|
|
2249a8bac0 | ||
|
|
c572e6a307 | ||
|
|
e444b6015c | ||
|
|
38dbed8e09 | ||
|
|
34c18ef000 | ||
|
|
0d4fde17e0 | ||
|
|
040a8c6bcc | ||
|
|
4e80570c4c | ||
|
|
91529cc435 | ||
|
|
ef3267833f | ||
|
|
a5ef50c9e7 | ||
|
|
6eee457898 | ||
|
|
fb6d7b3470 | ||
|
|
2d78fdabb8 | ||
|
|
94c31ceeb1 | ||
|
|
67d4da51ee | ||
|
|
6e4f66cc8b | ||
|
|
a4e781a231 | ||
|
|
f151892db5 | ||
|
|
c45fb73f36 | ||
|
|
848280d1f1 | ||
|
|
f7016b359f | ||
|
|
be58a279a5 | ||
|
|
909e6c4857 | ||
|
|
5c0b08f4f5 | ||
|
|
05d1cfa276 | ||
|
|
ae675ae4e1 | ||
|
|
d3b636d073 | ||
|
|
8b460f5944 | ||
|
|
bdfa32876b | ||
|
|
4a3472ebb2 | ||
|
|
9c804c1351 | ||
|
|
2a9c454baa | ||
|
|
1a9a6c3678 | ||
|
|
e1195e8b9d | ||
|
|
50ed55e8e2 | ||
|
|
d682295ccd | ||
|
|
5e19c1881f | ||
|
|
617ff52f18 | ||
|
|
5d3af62c0e | ||
|
|
ddd5aeba19 | ||
|
|
3cfcbe9a95 | ||
|
|
6bc793505d | ||
|
|
3b44160cff | ||
|
|
d9586c8d38 | ||
|
|
74df3fac4e | ||
|
|
06321b8e87 | ||
|
|
f3efb948fe | ||
|
|
432c03bf63 | ||
|
|
bfd224278b | ||
|
|
822ea6abc8 | ||
|
|
97437ee58b | ||
|
|
aa7fe0db29 | ||
|
|
237685d4a5 | ||
|
|
abbe630274 | ||
|
|
89d3b08e77 | ||
|
|
f826216a28 | ||
|
|
aa0a874ad0 | ||
|
|
2da26c0579 | ||
|
|
d34c844900 | ||
|
|
68b63632c4 | ||
|
|
d2de94778e | ||
|
|
4fd4a50d41 | ||
|
|
9d93820717 | ||
|
|
c57a7f0a41 | ||
|
|
1d15fcd072 | ||
|
|
e824b1129e | ||
|
|
0cd03c66e3 | ||
|
|
462b231dac | ||
|
|
e4a918850f | ||
|
|
d472af3517 | ||
|
|
98a587a347 | ||
|
|
5fd996876b | ||
|
|
b433d98c02 | ||
|
|
7006672b06 | ||
|
|
efec0c5cc3 | ||
|
|
16e71eac43 | ||
|
|
68b62abb52 | ||
|
|
b2f3479692 | ||
|
|
67d62ba164 | ||
|
|
e1fc60b8dd | ||
|
|
f32e696fef | ||
|
|
fc81298fac | ||
|
|
5987cfeaaf | ||
|
|
cd0ece4511 | ||
|
|
dc9f85ebb9 | ||
|
|
35a2055cda | ||
|
|
a1066776a5 | ||
|
|
4dae747343 | ||
|
|
d348a5b947 | ||
|
|
f0c413f40d | ||
|
|
846eee2f6c | ||
|
|
0b9ff68da1 | ||
|
|
7187e005d4 | ||
|
|
a5cd24e7ea | ||
|
|
dbe821baee | ||
|
|
04486c6472 | ||
|
|
2ee8ba9361 | ||
|
|
b07782cd89 | ||
|
|
305450b6e4 | ||
|
|
fdd0b853ed | ||
|
|
1d025204e7 | ||
|
|
12f759860e | ||
|
|
1bdbb5ddcc | ||
|
|
b573fb6555 | ||
|
|
b50a7bdbee | ||
|
|
5a5f10dfc8 | ||
|
|
e375b4a9ff | ||
|
|
ff141ab1ff | ||
|
|
b8537be219 | ||
|
|
8f1b034b2f | ||
|
|
71d0a07e0a | ||
|
|
d322342494 | ||
|
|
bc7ab17692 | ||
|
|
7a049c29bd | ||
|
|
1fc375b31a | ||
|
|
eee7f3991c | ||
|
|
2e3503517d | ||
|
|
15e58acc76 | ||
|
|
5aa5e3e09e | ||
|
|
25ae7b2c2b | ||
|
|
4b6dc9583a | ||
|
|
64eab1f7b3 | ||
|
|
182f57216f | ||
|
|
65b091a39a | ||
|
|
ed1a94531a | ||
|
|
4e12ffb0ae | ||
|
|
4800c201e4 | ||
|
|
dc9a9e5d96 | ||
|
|
6844f05c3d | ||
|
|
8f67f2c24c | ||
|
|
cc246bb9ac | ||
|
|
bf9f0a9e6d | ||
|
|
c3160bad44 | ||
|
|
94b8ac42ca | ||
|
|
a03e3d7eb9 | ||
|
|
a42ec08d16 | ||
|
|
fddb6cd9d8 | ||
|
|
841f016017 | ||
|
|
8e4afc95c7 | ||
|
|
8cec948699 | ||
|
|
31ae7c942c | ||
|
|
d0900626da | ||
|
|
0ee4cadca0 | ||
|
|
24b5a9c389 | ||
|
|
626220e9f3 | ||
|
|
323d68d460 | ||
|
|
db2091dd94 | ||
|
|
8216d85e52 | ||
|
|
a705eb1c61 | ||
|
|
77f664a6b1 | ||
|
|
c30057e923 | ||
|
|
06108b9479 | ||
|
|
16181523c9 | ||
|
|
7e0706cf83 | ||
|
|
bff67887fd | ||
|
|
351ff5eb48 | ||
|
|
051df14046 | ||
|
|
ee0318f697 | ||
|
|
a6fb1efcbe | ||
|
|
31fecc28a4 | ||
|
|
30b1efc354 | ||
|
|
7d721eb569 | ||
|
|
d48aac5beb | ||
|
|
14b56db99e | ||
|
|
bfe429de51 | ||
|
|
57ef5cfd07 | ||
|
|
4bbb7c0bcc | ||
|
|
4de70bff5e | ||
|
|
687f0c7dc0 | ||
|
|
f3d66e92ec | ||
|
|
9a91ae54d6 | ||
|
|
69422dc063 | ||
|
|
7bcd243ec3 | ||
|
|
8f70bea899 | ||
|
|
948c4275ad | ||
|
|
03a1159915 | ||
|
|
1c8fb298b4 | ||
|
|
b25a7cb370 | ||
|
|
140c365e4b | ||
|
|
8c93ceb728 | ||
|
|
ac50d7cf8a | ||
|
|
ecb873ff45 | ||
|
|
78baa04ecc | ||
|
|
b78f580d47 | ||
|
|
b115c75226 | ||
|
|
6bc092f3ae | ||
|
|
f99a266ce4 | ||
|
|
1f724d58e0 | ||
|
|
de4a246bb4 | ||
|
|
412b80da30 | ||
|
|
47319960a5 | ||
|
|
b22d218236 | ||
|
|
6eb82bc314 | ||
|
|
a06dd25d56 | ||
|
|
e1bb05bc52 | ||
|
|
8694a020ac | ||
|
|
1efb2e4d3d | ||
|
|
861726cefa | ||
|
|
81212d80c6 | ||
|
|
2235a809c4 | ||
|
|
3fe0f49ac0 | ||
|
|
03d8f9193b | ||
|
|
5e54969f6b | ||
|
|
18ef5eb1bf | ||
|
|
b5e3d92e9d | ||
|
|
ba8761e39e | ||
|
|
78f0b1562c | ||
|
|
5c28b30028 | ||
|
|
59267da72b | ||
|
|
36ad45c07d | ||
|
|
ecb2add791 | ||
|
|
9bbdaf300b | ||
|
|
bc492bb40e | ||
|
|
81221c4874 | ||
|
|
137b3d81fb | ||
|
|
6741f47ef1 |
@@ -5,7 +5,7 @@ AccessModifierOffset: -1
|
|||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: Align
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
AlignConsecutiveDeclarations: false
|
AlignConsecutiveDeclarations: false
|
||||||
AlignEscapedNewlinesLeft: true
|
AlignEscapedNewlines: Left
|
||||||
AlignOperands: true
|
AlignOperands: true
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
@@ -32,12 +32,20 @@ BraceWrapping:
|
|||||||
BeforeCatch: false
|
BeforeCatch: false
|
||||||
BeforeElse: false
|
BeforeElse: false
|
||||||
IndentBraces: false
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
BreakBeforeBraces: Attach
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
@@ -45,7 +53,11 @@ Cpp11BracedListStyle: true
|
|||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
DisableFormat: false
|
DisableFormat: false
|
||||||
ExperimentalAutoDetectBinPacking: false
|
ExperimentalAutoDetectBinPacking: false
|
||||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
- Regex: '^<.*\.h>'
|
- Regex: '^<.*\.h>'
|
||||||
Priority: 1
|
Priority: 1
|
||||||
@@ -53,9 +65,12 @@ IncludeCategories:
|
|||||||
Priority: 2
|
Priority: 2
|
||||||
- Regex: '.*'
|
- Regex: '.*'
|
||||||
Priority: 3
|
Priority: 3
|
||||||
|
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||||
IndentCaseLabels: true
|
IndentCaseLabels: true
|
||||||
IndentWidth: 2
|
IndentWidth: 2
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
MacroBlockBegin: ''
|
MacroBlockBegin: ''
|
||||||
MacroBlockEnd: ''
|
MacroBlockEnd: ''
|
||||||
@@ -64,6 +79,7 @@ NamespaceIndentation: None
|
|||||||
ObjCBlockIndentWidth: 2
|
ObjCBlockIndentWidth: 2
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
ObjCSpaceBeforeProtocolList: false
|
ObjCSpaceBeforeProtocolList: false
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
PenaltyBreakBeforeFirstCallParameter: 1
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
PenaltyBreakComment: 300
|
PenaltyBreakComment: 300
|
||||||
PenaltyBreakFirstLessLess: 120
|
PenaltyBreakFirstLessLess: 120
|
||||||
@@ -72,8 +88,10 @@ PenaltyExcessCharacter: 1000000
|
|||||||
PenaltyReturnTypeOnItsOwnLine: 200
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
PointerAlignment: Left
|
PointerAlignment: Left
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
SortIncludes: true
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
SpaceBeforeAssignmentOperators: true
|
SpaceBeforeAssignmentOperators: true
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
|
|||||||
45
.gitignore
vendored
45
.gitignore
vendored
@@ -1,15 +1,10 @@
|
|||||||
# WPIlib Specific
|
# WPIlib Specific
|
||||||
|
|
||||||
dependency-reduced-pom.xml
|
dependency-reduced-pom.xml
|
||||||
/wpilibj/src/athena/cpp/nivision/*.c
|
|
||||||
/wpilibj/src/athena/cpp/nivision/*.cpp
|
|
||||||
/wpilibj/src/athena/cpp/nivision/*.s
|
|
||||||
/wpilibj/src/athena/cpp/nivision/*_arm.ini
|
|
||||||
/wpilibj/src/athena/cpp/nivision/*.java
|
|
||||||
/wpilibj/src/athena/cpp/nivision/nivision_funcs.txt
|
|
||||||
/wpilibj/src/athena/cpp/nivision/imaqdx_funcs.txt
|
|
||||||
/wpilibj/src/shared/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
|
/wpilibj/src/shared/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
|
||||||
/wpilibc/shared/src/WPILibVersion.cpp
|
/wpilibc/shared/src/WPILibVersion.cpp
|
||||||
|
/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/WPILibVersion.java
|
||||||
|
/wpilibc/src/main/native/cpp/WPILibVersion.cpp
|
||||||
doxygen.log
|
doxygen.log
|
||||||
|
|
||||||
# Created by the jenkins test script
|
# Created by the jenkins test script
|
||||||
@@ -17,6 +12,8 @@ test-reports
|
|||||||
|
|
||||||
# IntelliJ
|
# IntelliJ
|
||||||
*.iml
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
# Created by http://www.gitignore.io
|
# Created by http://www.gitignore.io
|
||||||
@@ -157,6 +154,9 @@ local.properties
|
|||||||
*.pyc
|
*.pyc
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
|
# Gradle wrapper
|
||||||
|
!gradle-wrapper.jar
|
||||||
|
|
||||||
# External tool builders
|
# External tool builders
|
||||||
.externalToolBuilders/
|
.externalToolBuilders/
|
||||||
|
|
||||||
@@ -186,3 +186,34 @@ NO
|
|||||||
|
|
||||||
# VSCode
|
# VSCode
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
#classpaths and projects
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
|
||||||
|
#Visual Studio
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
*.VC.db-shm
|
||||||
|
*.VC.db-wal
|
||||||
|
|
||||||
|
*.sln
|
||||||
|
*.vcxproj
|
||||||
|
*.vcxproj.filters
|
||||||
|
|
||||||
|
# Visual Studio 2015 cache/options directory
|
||||||
|
.vs/
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
[gerrit]
|
|
||||||
host=usfirst.collab.net
|
|
||||||
port=29418
|
|
||||||
project=allwpilib
|
|
||||||
defaultbranch=master
|
|
||||||
73
.styleguide
73
.styleguide
@@ -1,68 +1,39 @@
|
|||||||
cExtensions {
|
cppHeaderFileInclude {
|
||||||
|
\.h$
|
||||||
|
\.hpp$
|
||||||
|
\.inc$
|
||||||
}
|
}
|
||||||
|
|
||||||
cppHeaderExtensions {
|
cppSrcFileInclude {
|
||||||
h
|
\.cpp$
|
||||||
inc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cppSrcExtensions {
|
generatedFileExclude {
|
||||||
cpp
|
gmock/
|
||||||
}
|
ni-libraries/include/
|
||||||
|
ni-libraries/lib/
|
||||||
otherExtensions {
|
hal/src/main/native/athena/ctre/
|
||||||
java
|
hal/src/main/native/athena/frccansae/
|
||||||
}
|
hal/src/main/native/athena/visa/
|
||||||
|
hal/src/main/native/include/ctre/
|
||||||
genFolderExclude {
|
UsageReporting\.h$
|
||||||
\.vscode
|
|
||||||
FRC_FPGA_ChipObject
|
|
||||||
NetworkCommunication
|
|
||||||
ctre
|
|
||||||
frccansae
|
|
||||||
gtest
|
|
||||||
i2clib
|
|
||||||
msgs
|
|
||||||
ni-libraries
|
|
||||||
ni/vision
|
|
||||||
spilib
|
|
||||||
wpilibj/src/athena/cpp/nivision
|
|
||||||
visa
|
|
||||||
}
|
|
||||||
|
|
||||||
genFileExclude {
|
|
||||||
NIIMAQdx\.h$
|
|
||||||
can_proto\.h$
|
|
||||||
nivision\.h$
|
|
||||||
}
|
|
||||||
|
|
||||||
modifiableFolderExclude {
|
|
||||||
\.git
|
|
||||||
\.gradle
|
|
||||||
__pycache__
|
|
||||||
build
|
|
||||||
wpilibj/src/athena/cpp/include
|
|
||||||
wpilibj/src/athena/cpp/lib
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modifiableFileExclude {
|
modifiableFileExclude {
|
||||||
\.jar$
|
wpilibj/src/arm-linux-jni/
|
||||||
|
wpilibj/src/main/native/cpp/
|
||||||
\.patch$
|
\.patch$
|
||||||
\.png$
|
\.png$
|
||||||
\.py$
|
\.py$
|
||||||
\.so$
|
\.so$
|
||||||
}
|
}
|
||||||
|
|
||||||
includeRelated {
|
|
||||||
}
|
|
||||||
|
|
||||||
includeCSys {
|
|
||||||
}
|
|
||||||
|
|
||||||
includeCppSys {
|
|
||||||
}
|
|
||||||
|
|
||||||
includeOtherLibs {
|
includeOtherLibs {
|
||||||
|
^HAL/
|
||||||
|
^llvm/
|
||||||
|
^networktables/
|
||||||
|
^opencv2/
|
||||||
|
^support/
|
||||||
}
|
}
|
||||||
|
|
||||||
includeProject {
|
includeProject {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/* Copyright (c) FIRST {year}. All Rights Reserved.{padding}*/
|
/* Copyright (c) {year} FIRST. All Rights Reserved.{padding}*/
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||||
/* the project. */
|
/* the project. */
|
||||||
|
|||||||
38
.travis.yml
38
.travis.yml
@@ -1,26 +1,40 @@
|
|||||||
sudo: required
|
sudo: true
|
||||||
dist: trusty
|
dist: trusty
|
||||||
language: java
|
language: java
|
||||||
|
|
||||||
before_install:
|
addons:
|
||||||
- sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
|
apt:
|
||||||
- wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
|
sources:
|
||||||
- sudo add-apt-repository ppa:wpilib/toolchain -y
|
- deadsnakes
|
||||||
- sudo apt-get update -q || true
|
- ubuntu-toolchain-r-test
|
||||||
- sudo apt-get install frc-toolchain libgazebo7-dev protobuf-compiler libprotobuf-dev python3 clang-format-3.8 -y
|
packages:
|
||||||
|
- g++-6
|
||||||
|
- python3.5
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- sudo sh -c 'echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" > /etc/apt/sources.list.d/llvm.list'
|
||||||
|
- wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||||
|
- sudo apt-get update -q || true
|
||||||
|
- sudo apt-get install clang-format-5.0 -y
|
||||||
|
|
||||||
|
install:
|
||||||
|
- wget https://bootstrap.pypa.io/get-pip.py
|
||||||
|
- sudo python3.5 get-pip.py
|
||||||
|
- python3.5 -m pip install --user wpiformat
|
||||||
|
- mkdir -p $HOME/latest-gcc-symlinks # see travis-ci/travis-ci#3668
|
||||||
|
- ln -s /usr/bin/g++-6 $HOME/latest-gcc-symlinks/g++
|
||||||
|
- ln -s /usr/bin/gcc-6 $HOME/latest-gcc-symlinks/gcc
|
||||||
|
- export PATH=$HOME/latest-gcc-symlinks:$PATH
|
||||||
|
|
||||||
before_cache:
|
before_cache:
|
||||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/.gradle/caches/
|
- $HOME/.gradle/caches/
|
||||||
- $HOME/.gradle/wrapper/
|
- $HOME/.gradle/wrapper/
|
||||||
|
|
||||||
before_script:
|
|
||||||
- git clone git://github.com/wpilibsuite/styleguide $HOME/styleguide
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- WPI_FORMAT=$HOME/styleguide python3 styleguide/format.py
|
- python3.5 -m wpiformat -y 2018 -clang 5.0
|
||||||
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
|
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
|
||||||
- ./gradlew build -PmakeSim
|
- ./gradlew --no-daemon --console=plain -PskipAthena :hal:halSimSharedLibrary :wpilibc:wpilibcSharedLibrary :wpilibj:wpilibJNISharedSharedLibrary :wpilibj:jar
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
|
||||||
project(AllC++Sim)
|
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
include (FindPkgConfig)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
#check for depenedencies
|
|
||||||
find_package(gazebo REQUIRED)
|
|
||||||
find_package(Boost COMPONENTS system filesystem REQUIRED)
|
|
||||||
|
|
||||||
#on windows we produce .dlls with no prefix
|
|
||||||
if(WIN32)
|
|
||||||
#allows us to define constexpr and noexcept in macros
|
|
||||||
#since msvc 2013 doesn't support them
|
|
||||||
add_definitions(-D_ALLOW_KEYWORD_MACROS)
|
|
||||||
|
|
||||||
# defines things like M_PI
|
|
||||||
add_definitions(-D_USE_MATH_DEFINES)
|
|
||||||
|
|
||||||
# get rid of min max macros on windows
|
|
||||||
add_definitions(-DNOMINMAX)
|
|
||||||
|
|
||||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
|
||||||
|
|
||||||
SET(CMAKE_FIND_LIBRARY_PREFIXES "")
|
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFRC_SIMULATOR /MDd /Zi")
|
|
||||||
else ()
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++1y -DFRC_SIMULATOR -Wno-unused-parameter -pthread -fPIC -fpermissive")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include_directories("build")
|
|
||||||
add_subdirectory(simulation/gz_msgs)
|
|
||||||
add_subdirectory(wpilibc/sim)
|
|
||||||
add_subdirectory(simulation/frc_gazebo_plugins)
|
|
||||||
@@ -37,7 +37,7 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
|
|||||||
|
|
||||||
## Coding Guidelines
|
## Coding Guidelines
|
||||||
|
|
||||||
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running format.py, which is in the styleguide directory, is required for all contributions and is enforced by our continuous integration system.
|
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
|
||||||
|
|
||||||
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
|
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
|
||||||
|
|
||||||
|
|||||||
24
LICENSE.txt
Normal file
24
LICENSE.txt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
Copyright (c) 2009-2017 FIRST
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the FIRST nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
16
README.md
16
README.md
@@ -23,15 +23,19 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
- A C++ compiler
|
||||||
|
- On Linux, gcc works fine
|
||||||
|
- On Windows, you need Visual Studio 2015 (the free community edition works fine).
|
||||||
|
Make sure to select the C++ Programming Language for installation
|
||||||
- [ARM Compiler Toolchain](http://first.wpi.edu/FRC/roborio/toolchains/)
|
- [ARM Compiler Toolchain](http://first.wpi.edu/FRC/roborio/toolchains/)
|
||||||
|
* Note that for 2017-2018 and beyond, you will need version 5 or greater of gcc
|
||||||
- Doxygen (Only required if you want to build the C++ documentation)
|
- Doxygen (Only required if you want to build the C++ documentation)
|
||||||
- [format.py](https://github.com/wpilibsuite/styleguide)
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
Clone the WPILib repository. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
|
Clone the WPILib repository. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
|
||||||
|
|
||||||
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for format.py setup instructions.
|
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for wpiformat setup instructions.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
@@ -47,6 +51,12 @@ To build a specific subproject, such as WPILibC, you must access the subproject
|
|||||||
./gradlew :wpilibc:build
|
./gradlew :wpilibc:build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
|
||||||
|
```
|
||||||
|
|
||||||
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
|
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -67,7 +77,7 @@ The gradlew wrapper only exists in the root of the main project, so be sure to r
|
|||||||
|
|
||||||
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
|
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
|
||||||
|
|
||||||
format.py can be executed in either the styleguide or root directories of the repository via `python3 format.py` or `./format.py`.
|
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
|
||||||
|
|
||||||
## Publishing
|
## Publishing
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
|
||||||
INCLUDE(CMakeForceCompiler)
|
|
||||||
set(ARM_PREFIX arm-frc-linux-gnueabi)
|
|
||||||
set(CMAKE_SYSTEM_NAME Linux)
|
|
||||||
CMAKE_FORCE_CXX_COMPILER(${ARM_PREFIX}-g++ GNU)
|
|
||||||
CMAKE_FORCE_C_COMPILER(${ARM_PREFIX}-gcc GNU)
|
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++1y -Wformat=2 -Wall -Wextra -Werror -pedantic -Wno-psabi" CACHE STRING "" FORCE)
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3" CACHE STRING "" FORCE)
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g" CACHE STRING "" FORCE) # still want debugging for release?
|
|
||||||
198
build.gradle
198
build.gradle
@@ -1,23 +1,173 @@
|
|||||||
plugins {
|
import edu.wpi.first.nativeutils.NativeUtils
|
||||||
id 'net.ltgt.errorprone' version '0.0.8'
|
import edu.wpi.first.nativeutils.tasks.JNIHeaders
|
||||||
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '1.2'
|
|
||||||
}
|
|
||||||
|
|
||||||
def enableSimulation = hasProperty('enableSimulation')
|
|
||||||
|
|
||||||
if (!hasProperty('repo')) {
|
|
||||||
ext.repo = 'development'
|
|
||||||
}
|
|
||||||
|
|
||||||
ext.simulationInstallDir = "$rootDir/build/install/simulation"
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
ext.enableSimulation = enableSimulation
|
|
||||||
ext.repo = repo
|
|
||||||
|
|
||||||
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenLocal()
|
||||||
|
maven {
|
||||||
|
url "https://plugins.gradle.org/m2/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.5.1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'net.ltgt.errorprone' version '0.0.10'
|
||||||
|
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '2.0'
|
||||||
|
id 'idea'
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.licenseFile = file("$rootDir/LICENSE.txt")
|
||||||
|
|
||||||
|
ext.getJNIHeadersClass = {
|
||||||
|
return JNIHeaders
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.getClassifier = { binary->
|
||||||
|
return NativeUtils.getClassifier(binary)
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.getPlatformPath = { binary->
|
||||||
|
return NativeUtils.getPlatformPath(binary)
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.createComponentZipTasks = { components, name, base, type, project, func ->
|
||||||
|
def configMap = [:]
|
||||||
|
components.each {
|
||||||
|
if (it in NativeLibrarySpec && it.name == name) {
|
||||||
|
it.binaries.each {
|
||||||
|
def target = getClassifier(it)
|
||||||
|
if (configMap.containsKey(target)) {
|
||||||
|
configMap.get(target).add(it)
|
||||||
|
} else {
|
||||||
|
configMap.put(target, [])
|
||||||
|
configMap.get(target).add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def taskList = []
|
||||||
|
def outputsFolder = file("$project.buildDir/outputs")
|
||||||
|
def baseN = base + name
|
||||||
|
configMap.each { key, value ->
|
||||||
|
def task = project.tasks.create(baseN + "-${key}", type) {
|
||||||
|
description = 'Creates component archive for platform ' + key
|
||||||
|
destinationDir = outputsFolder
|
||||||
|
classifier = key
|
||||||
|
baseName = baseN + '-classifier'
|
||||||
|
duplicatesStrategy = 'exclude'
|
||||||
|
|
||||||
|
from(licenseFile) {
|
||||||
|
into '/'
|
||||||
|
}
|
||||||
|
|
||||||
|
func(it, value)
|
||||||
|
}
|
||||||
|
taskList.add(task)
|
||||||
|
|
||||||
|
project.build.dependsOn task
|
||||||
|
|
||||||
|
project.artifacts {
|
||||||
|
task
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return taskList
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.createAllCombined = { list, name, base, type, project ->
|
||||||
|
def outputsFolder = file("$project.buildDir/outputs")
|
||||||
|
def baseN = base + name
|
||||||
|
def task = project.tasks.create(baseN + '-all', type) {
|
||||||
|
description = 'Creates component archive for all classifiers'
|
||||||
|
destinationDir = outputsFolder
|
||||||
|
classifier = 'all'
|
||||||
|
baseName = baseN + '-classifier'
|
||||||
|
duplicatesStrategy = 'exclude'
|
||||||
|
|
||||||
|
list.each {
|
||||||
|
it.outputs.files.each {
|
||||||
|
from project.zipTree(it)
|
||||||
|
}
|
||||||
|
dependsOn it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.build.dependsOn task
|
||||||
|
|
||||||
|
project.artifacts {
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
return task
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.includeStandardZipFormat = { task, value ->
|
||||||
|
value.each { binary->
|
||||||
|
if (binary.buildable) {
|
||||||
|
if (binary instanceof SharedLibraryBinarySpec) {
|
||||||
|
task.dependsOn binary.buildTask
|
||||||
|
task.from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) {
|
||||||
|
into getPlatformPath(binary) + '/shared'
|
||||||
|
}
|
||||||
|
task.from (binary.sharedLibraryFile) {
|
||||||
|
into getPlatformPath(binary) + '/shared'
|
||||||
|
}
|
||||||
|
task.from (binary.sharedLibraryLinkFile) {
|
||||||
|
into getPlatformPath(binary) + '/shared'
|
||||||
|
}
|
||||||
|
} else if (binary instanceof StaticLibraryBinarySpec) {
|
||||||
|
task.dependsOn binary.buildTask
|
||||||
|
task.from (binary.staticLibraryFile) {
|
||||||
|
into getPlatformPath(binary) + '/static'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the WPILibVersioningPlugin is setup by setting the release type, if releaseType wasn't
|
||||||
|
// already specified on the command line
|
||||||
|
if (!hasProperty('releaseType')) {
|
||||||
|
WPILibVersion {
|
||||||
|
releaseType = 'dev'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def pubVersion
|
||||||
|
if (project.hasProperty("publishVersion")) {
|
||||||
|
pubVersion = project.publishVersion
|
||||||
|
} else {
|
||||||
|
pubVersion = WPILibVersion.version
|
||||||
|
}
|
||||||
|
|
||||||
|
def outputsFolder = file("$buildDir/outputs")
|
||||||
|
|
||||||
|
def versionFile = file("$outputsFolder/version.txt")
|
||||||
|
|
||||||
|
task outputVersions() {
|
||||||
|
description = 'Prints the versions of wpilib to a file for use by the downstream packaging project'
|
||||||
|
group = 'Build'
|
||||||
|
outputs.files(versionFile)
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
buildDir.mkdir()
|
||||||
|
outputsFolder.mkdir()
|
||||||
|
}
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
versionFile.write pubVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task build() {}
|
||||||
|
|
||||||
|
build.dependsOn outputVersions
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete buildDir
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
@@ -25,12 +175,14 @@ subprojects {
|
|||||||
apply plugin: 'idea'
|
apply plugin: 'idea'
|
||||||
apply plugin: 'checkstyle'
|
apply plugin: 'checkstyle'
|
||||||
|
|
||||||
checkstyle {
|
repositories {
|
||||||
toolVersion = "6.18"
|
mavenCentral()
|
||||||
configFile = new File(rootDir, "styleguide/checkstyle.xml")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.armBuild = true
|
checkstyle {
|
||||||
|
toolVersion = "8.1"
|
||||||
|
configFile = new File(rootDir, "styleguide/checkstyle.xml")
|
||||||
|
}
|
||||||
|
|
||||||
// Disables doclint in java 8.
|
// Disables doclint in java 8.
|
||||||
if (JavaVersion.current().isJava8Compatible()) {
|
if (JavaVersion.current().isJava8Compatible()) {
|
||||||
@@ -45,8 +197,6 @@ subprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: 'cppSettings.gradle'
|
|
||||||
|
|
||||||
task wrapper(type: Wrapper) {
|
task wrapper(type: Wrapper) {
|
||||||
gradleVersion = '3.0'
|
gradleVersion = '4.1'
|
||||||
}
|
}
|
||||||
|
|||||||
235
config.gradle
Normal file
235
config.gradle
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
import edu.wpi.first.nativeutils.*
|
||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
|
||||||
|
def windowsCompilerArgs = ['/EHsc', '/DNOMINMAX', '/Zi', '/FS', '/Zc:inline', '/MT']
|
||||||
|
def windowsReleaseCompilerArgs = ['/O2']
|
||||||
|
def windowsLinkerArgs = [ '/DEBUG:FULL' ]
|
||||||
|
def windowsReleaseLinkerArgs = [ '/OPT:REF', '/OPT:ICF' ]
|
||||||
|
|
||||||
|
def linuxCompilerArgs = ['-std=c++11', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g',
|
||||||
|
'-Wno-unused-parameter', '-fPIC', '-rdynamic', '-Wno-error=deprecated-declarations', '-pthread']
|
||||||
|
def linuxLinkerArgs = ['-rdynamic', '-pthread']
|
||||||
|
def linuxReleaseCompilerArgs = ['-Og']
|
||||||
|
def linuxDebugCompilerArgs = ['-O0']
|
||||||
|
def linux32BitArg = '-m32'
|
||||||
|
|
||||||
|
def macCompilerArgs = ['-std=c++11', '-Wall', '-Wextra', '-Werror', '-pedantic-errors', '-fPIC', '-g',
|
||||||
|
'-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wno-unused-private-field',
|
||||||
|
'-Wno-unused-const-variable', '-pthread']
|
||||||
|
def macReleaseCompilerArgs = ['-O2']
|
||||||
|
def macDebugCompilerArgs = ['-O0']
|
||||||
|
def mac32BitArg = '-m32'
|
||||||
|
|
||||||
|
def buildAll = project.hasProperty('buildAll')
|
||||||
|
|
||||||
|
def windows64PlatformDetect = {
|
||||||
|
def arch = System.getProperty("os.arch")
|
||||||
|
def isWin = OperatingSystem.current().isWindows()
|
||||||
|
if (buildAll) {
|
||||||
|
return isWin
|
||||||
|
} else {
|
||||||
|
return isWin && arch == 'amd64'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def windows32PlatformDetect = {
|
||||||
|
def arch = System.getProperty("os.arch")
|
||||||
|
def isWin = OperatingSystem.current().isWindows()
|
||||||
|
if (buildAll) {
|
||||||
|
return isWin
|
||||||
|
} else {
|
||||||
|
return isWin && arch == 'x86'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def linux32IntelPlatformDetect = {
|
||||||
|
def arch = System.getProperty("os.arch")
|
||||||
|
def isLinux = OperatingSystem.current().isLinux()
|
||||||
|
def isIntel = (arch == 'amd64' || arch == 'i386')
|
||||||
|
if (buildAll) {
|
||||||
|
return isLinux && isIntel
|
||||||
|
} else {
|
||||||
|
return isLinux && arch == 'i386'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def linux64IntelPlatformDetect = {
|
||||||
|
def arch = System.getProperty("os.arch")
|
||||||
|
def isLinux = OperatingSystem.current().isLinux()
|
||||||
|
def isIntel = (arch == 'amd64' || arch == 'i386')
|
||||||
|
if (buildAll) {
|
||||||
|
return isLinux && isIntel
|
||||||
|
} else {
|
||||||
|
return isLinux && arch == 'amd64'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def linuxArmPlatformDetect = {
|
||||||
|
def arch = System.getProperty("os.arch")
|
||||||
|
def isIntel = (arch == 'amd64' || arch == 'i386')
|
||||||
|
return OperatingSystem.current().isLinux() && !isIntel
|
||||||
|
}
|
||||||
|
|
||||||
|
def mac64PlatformDetect = {
|
||||||
|
def arch = System.getProperty("os.arch")
|
||||||
|
def isMac = OperatingSystem.current().isMacOsX()
|
||||||
|
if (buildAll) {
|
||||||
|
return isMac
|
||||||
|
} else {
|
||||||
|
return isMac && arch == 'x86_64'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def mac32PlatformDetect = {
|
||||||
|
def arch = System.getProperty("os.arch")
|
||||||
|
def isMac = OperatingSystem.current().isMacOsX()
|
||||||
|
if (buildAll) {
|
||||||
|
return isMac
|
||||||
|
} else {
|
||||||
|
return isMac && arch == 'x86'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!project.hasProperty('skipAthena')) {
|
||||||
|
model {
|
||||||
|
buildConfigs {
|
||||||
|
roboRio(CrossBuildConfig) {
|
||||||
|
architecture = 'athena'
|
||||||
|
operatingSystem = 'linux'
|
||||||
|
toolChainPrefix = 'arm-frc-linux-gnueabi-'
|
||||||
|
compilerArgs = linuxCompilerArgs
|
||||||
|
linkerArgs = linuxLinkerArgs
|
||||||
|
debugCompilerArgs = linuxDebugCompilerArgs
|
||||||
|
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||||
|
releaseStripBinaries = true
|
||||||
|
compilerFamily = 'Gcc'
|
||||||
|
exclude << 'halSim'
|
||||||
|
exclude << 'halSimStaticDeps'
|
||||||
|
exclude << 'halSimTestingBase'
|
||||||
|
exclude << 'wpilibcTestingBase'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!project.hasProperty('onlyAthena')) {
|
||||||
|
model {
|
||||||
|
buildConfigs {
|
||||||
|
winX86(BuildConfig) {
|
||||||
|
architecture = 'x86'
|
||||||
|
operatingSystem = 'windows'
|
||||||
|
compilerArgs = windowsCompilerArgs
|
||||||
|
linkerArgs = windowsLinkerArgs
|
||||||
|
releaseCompilerArgs = windowsReleaseCompilerArgs
|
||||||
|
releaseLinkerArgs = windowsReleaseLinkerArgs
|
||||||
|
compilerFamily = 'VisualCpp'
|
||||||
|
detectPlatform = windows32PlatformDetect
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
winX64(BuildConfig) {
|
||||||
|
architecture = 'x86-64'
|
||||||
|
operatingSystem = 'windows'
|
||||||
|
compilerArgs = windowsCompilerArgs
|
||||||
|
linkerArgs = windowsLinkerArgs
|
||||||
|
releaseCompilerArgs = windowsReleaseCompilerArgs
|
||||||
|
releaseLinkerArgs = windowsReleaseLinkerArgs
|
||||||
|
compilerFamily = 'VisualCpp'
|
||||||
|
detectPlatform = windows64PlatformDetect
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
/* Disable 32 bit linux until we can figure out jenkins
|
||||||
|
linuxX86(BuildConfig) {
|
||||||
|
architecture = 'x86'
|
||||||
|
operatingSystem = 'linux'
|
||||||
|
compilerArgs = linuxCompilerArgs
|
||||||
|
compilerArgs << linux32BitArg
|
||||||
|
linkerArgs = linuxLinkerArgs
|
||||||
|
linkerArgs << linux32BitArg
|
||||||
|
debugCompilerArgs = linuxDebugCompilerArgs
|
||||||
|
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||||
|
releaseStripBinaries = true
|
||||||
|
compilerFamily = 'Gcc'
|
||||||
|
detectPlatform = linux32IntelPlatformDetect
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
linuxX64(BuildConfig) {
|
||||||
|
architecture = 'x86-64'
|
||||||
|
operatingSystem = 'linux'
|
||||||
|
compilerArgs = linuxCompilerArgs
|
||||||
|
linkerArgs = linuxLinkerArgs
|
||||||
|
debugCompilerArgs = linuxDebugCompilerArgs
|
||||||
|
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||||
|
releaseStripBinaries = true
|
||||||
|
compilerFamily = 'Gcc'
|
||||||
|
detectPlatform = linux64IntelPlatformDetect
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
/* 32 bit Mac OS X not supported by OpenCV.
|
||||||
|
* If support is ever added, will add this back in
|
||||||
|
macX86(BuildConfig) {
|
||||||
|
architecture = 'x86'
|
||||||
|
operatingSystem = 'osx'
|
||||||
|
compilerArgs = macCompilerArgs
|
||||||
|
compilerArgs << mac32BitArg
|
||||||
|
linkerArgs << mac32BitArg
|
||||||
|
debugCompilerArgs = macDebugCompilerArgs
|
||||||
|
releaseCompilerArgs = macReleaseCompilerArgs
|
||||||
|
releaseStripBinaries = true
|
||||||
|
compilerFamily = 'Clang'
|
||||||
|
detectPlatform = mac32PlatformDetect
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
macX64(BuildConfig) {
|
||||||
|
architecture = 'x86-64'
|
||||||
|
operatingSystem = 'osx'
|
||||||
|
compilerArgs = macCompilerArgs
|
||||||
|
debugCompilerArgs = macDebugCompilerArgs
|
||||||
|
releaseCompilerArgs = macReleaseCompilerArgs
|
||||||
|
releaseStripBinaries = true
|
||||||
|
compilerFamily = 'Clang'
|
||||||
|
detectPlatform = mac64PlatformDetect
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.hasProperty('linuxCross')) {
|
||||||
|
model {
|
||||||
|
buildConfigs {
|
||||||
|
linuxArm(CrossBuildConfig) {
|
||||||
|
architecture = 'nativearm'
|
||||||
|
operatingSystem = 'linux'
|
||||||
|
toolChainPrefix = 'PLEASE_PROVIDE_A_COMPILER_NAME'
|
||||||
|
compilerArgs = linuxCompilerArgs
|
||||||
|
linkerArgs = linuxLinkerArgs
|
||||||
|
debugCompilerArgs = linuxDebugCompilerArgs
|
||||||
|
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||||
|
releaseStripBinaries = true
|
||||||
|
skipByDefault = true
|
||||||
|
compilerFamily = 'Gcc'
|
||||||
|
exclude << 'gmock'
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model {
|
||||||
|
buildConfigs {
|
||||||
|
linuxArm(BuildConfig) {
|
||||||
|
architecture = 'nativearm'
|
||||||
|
operatingSystem = 'linux'
|
||||||
|
compilerArgs = linuxCompilerArgs
|
||||||
|
linkerArgs = linuxLinkerArgs
|
||||||
|
debugCompilerArgs = linuxDebugCompilerArgs
|
||||||
|
releaseCompilerArgs = linuxReleaseCompilerArgs
|
||||||
|
releaseStripBinaries = true
|
||||||
|
compilerFamily = 'Gcc'
|
||||||
|
detectPlatform = linuxArmPlatformDetect
|
||||||
|
exclude << 'halAthena'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
:: This file is a helper for allC++Sim
|
|
||||||
::
|
|
||||||
:: Usage: cd /build && ../configure
|
|
||||||
::
|
|
||||||
:: WARNING -- this is only temporary, and only meant for debug, and only works on my computer
|
|
||||||
@set WS=C:\Users\peter\gz-ws
|
|
||||||
@set BOOST_PATH=%WS%\boost_1_56_0
|
|
||||||
@set BOOST_LIBRARY_DIR=%BOOST_PATH%\lib64-msvc-12.0
|
|
||||||
|
|
||||||
@set PROTOBUF_PATH=%WS%\protobuf-2.6.0-win64-vc12
|
|
||||||
|
|
||||||
@set OGRE_PATH=%WS%\ogre_src_v1-8-1-vc12-x64-release-debug\build\install\Debug
|
|
||||||
@set OGRE_INCLUDE_DIR=%OGRE_PATH%\include;%OGRE_PATH%\include\OGRE;%OGRE_PATH%\include\OGRE\RTShaderSystem;%OGRE_PATH%\include\OGRE\Terrain;%OGRE_PATH%\include\OGRE\Paging
|
|
||||||
@set OGRE_LIBRARY_DIR=%OGRE_PATH%\lib\Debug
|
|
||||||
set OGRE_LIB_SUFFIX=_d.lib
|
|
||||||
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreOverlay%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
|
|
||||||
@set OGRE_LIBS=%OGRE_LIBRARY_DIR%\OgreMain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreRTShaderSystem%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgreTerrain%OGRE_LIB_SUFFIX%;%OGRE_LIBRARY_DIR%\OgrePaging%OGRE_LIB_SUFFIX%
|
|
||||||
|
|
||||||
@set FREEIMAGE_PATH=%WS%\FreeImage-vc12-x64-release-debug
|
|
||||||
@set FREEIMAGE_INCLUDE_DIR=%FREEIMAGE_PATH%\Source
|
|
||||||
|
|
||||||
@set TBB_PATH=%WS%\tbb43_20141023oss
|
|
||||||
@set TBB_INCLUDEDIR=%TBB_PATH%\include
|
|
||||||
|
|
||||||
@set DLFCN_WIN32_PATH=%WS%\dlfcn-win32-vc12-x64-release-debug\build\install\Debug
|
|
||||||
@set DLFCN_WIN32_INCLUDE_DIR=%DLFCN_WIN32_PATH%\include
|
|
||||||
|
|
||||||
@set TINY_XML_INCLUDE_DIR=%WS%\sdformat\src\win\tinyxml
|
|
||||||
|
|
||||||
@set GAZEBO_PATH=%WS%\gazebo\build\install\Debug\lib\cmake\gazebo
|
|
||||||
@set SDFORMAT_PATH=%WS%\sdformat\build\install\Debug\lib\cmake\sdformat
|
|
||||||
@set IGNITION-MATH_PATH=%WS%\ign-math\build\install\Debug\lib\cmake\ignition-math2
|
|
||||||
|
|
||||||
@set INCLUDE=%TINY_XML_INCLUDE_DIR%;%FREEIMAGE_INCLUDE_DIR%;%TBB_INCLUDEDIR%;%DLFCN_WIN32_INCLUDE_DIR%;%INCLUDE%
|
|
||||||
@set LIB=%LIB%
|
|
||||||
|
|
||||||
cmake -G "NMake Makefiles"^
|
|
||||||
-DCMAKE_INSTALL_PREFIX=build^
|
|
||||||
-DCMAKE_PREFIX_PATH="%GAZEBO_PATH%;%SDFORMAT_PATH%;%IGNITION-MATH_PATH%"^
|
|
||||||
-DOGRE_FOUND=1^
|
|
||||||
-DOGRE_INCLUDE_DIRS="%OGRE_INCLUDE_DIR%"^
|
|
||||||
-DOGRE_LIBRARIES="%OGRE_LIBS%"^
|
|
||||||
-DPROTOBUF_SRC_ROOT_FOLDER="%PROTOBUF_PATH%"^
|
|
||||||
-DBOOST_ROOT="%BOOST_PATH%"^
|
|
||||||
-DBOOST_LIBRARYDIR="%BOOST_LIBRARY_DIR%"^
|
|
||||||
..
|
|
||||||
@@ -1,298 +0,0 @@
|
|||||||
// These add the nilibraries shared library to the linker args
|
|
||||||
def niLibraryPath = file('ni-libraries').path
|
|
||||||
def niLibrary = niLibraryPath + "/libnilibraries.so"
|
|
||||||
|
|
||||||
task downloadArmNetworkTables() {
|
|
||||||
description = 'Downloads the C++ ARM NetworkTables maven dependency.'
|
|
||||||
group = 'WPILib'
|
|
||||||
def depFolder = "$buildDir/dependencies"
|
|
||||||
def ntZip = file("$depFolder/ntcore-arm.zip")
|
|
||||||
outputs.file(ntZip)
|
|
||||||
def armNetTables
|
|
||||||
|
|
||||||
doFirst {
|
|
||||||
def armNtDependency = project.dependencies.create('edu.wpi.first.wpilib.networktables.cpp:NetworkTables:+:arm@zip')
|
|
||||||
def armConfig = project.configurations.detachedConfiguration(armNtDependency)
|
|
||||||
armConfig.setTransitive(false)
|
|
||||||
armNetTables = armConfig.files[0].canonicalFile
|
|
||||||
}
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
copy {
|
|
||||||
from armNetTables
|
|
||||||
rename 'NetworkTables(.+)', 'ntcore-arm.zip'
|
|
||||||
into depFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty('makeSim')) {
|
|
||||||
task downloadDesktopNetworkTables() {
|
|
||||||
description = 'Downloads the C++ Desktop NetworkTables maven dependency.'
|
|
||||||
group = 'WPILib'
|
|
||||||
def depFolder = "$buildDir/dependencies"
|
|
||||||
def ntZip = file("$depFolder/ntcore-desk.zip")
|
|
||||||
outputs.file(ntZip)
|
|
||||||
def desktopNetTables
|
|
||||||
doFirst {
|
|
||||||
def desktopNtDependency = project.dependencies.create("edu.wpi.first.wpilib.networktables.cpp:NetworkTables:+:desktop@zip")
|
|
||||||
def desktopConfig = project.configurations.detachedConfiguration(desktopNtDependency)
|
|
||||||
desktopConfig.setTransitive(false)
|
|
||||||
desktopNetTables = desktopConfig.files[0].canonicalFile
|
|
||||||
}
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
copy {
|
|
||||||
from desktopNetTables
|
|
||||||
rename 'NetworkTables(.+)', 'ntcore-desk.zip'
|
|
||||||
into depFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def netTablesUnzipLocation = "$buildDir/networktables"
|
|
||||||
|
|
||||||
// Create a task that will unzip the networktables files into a temporary build directory
|
|
||||||
task unzipNetworkTables(type: Copy) {
|
|
||||||
description = 'Unzips the networktables maven dependency so that the include files and libraries can be used'
|
|
||||||
group = 'WPILib'
|
|
||||||
dependsOn downloadArmNetworkTables
|
|
||||||
|
|
||||||
if (project.hasProperty('makeSim')) {
|
|
||||||
dependsOn downloadDesktopNetworkTables
|
|
||||||
from zipTree(downloadDesktopNetworkTables.outputs.files.singleFile)
|
|
||||||
}
|
|
||||||
from zipTree(downloadArmNetworkTables.outputs.files.singleFile)
|
|
||||||
into netTablesUnzipLocation
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadArmWpiUtil() {
|
|
||||||
description = 'Downloads the C++ ARM wpiutil maven dependency.'
|
|
||||||
group = 'WPILib'
|
|
||||||
def depFolder = "$buildDir/dependencies"
|
|
||||||
def utilZip = file("$depFolder/wpiutil-arm.zip")
|
|
||||||
outputs.file(utilZip)
|
|
||||||
def armWpiUtil
|
|
||||||
|
|
||||||
doFirst {
|
|
||||||
def armWpiUtilDependency = project.dependencies.create("edu.wpi.first.wpilib:wpiutil:+:arm@zip")
|
|
||||||
def armWpiUtilConfig = project.configurations.detachedConfiguration(armWpiUtilDependency)
|
|
||||||
armWpiUtilConfig.setTransitive(false)
|
|
||||||
armWpiUtil = armWpiUtilConfig.files[0].canonicalFile
|
|
||||||
}
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
copy {
|
|
||||||
from armWpiUtil
|
|
||||||
rename 'wpiutil(.+)', 'wpiutil-arm.zip'
|
|
||||||
into depFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty('makeSim')) {
|
|
||||||
task downloadDesktopWpiUtil() {
|
|
||||||
description = 'Downloads the C++ Desktop wpiutil maven dependency.'
|
|
||||||
group = 'WPILib'
|
|
||||||
def depFolder = "$buildDir/dependencies"
|
|
||||||
def wpiutilZip = file("$depFolder/wpiutil-desk.zip")
|
|
||||||
outputs.file(wpiutilZip)
|
|
||||||
def wpiUtil
|
|
||||||
|
|
||||||
doFirst {
|
|
||||||
def desktopWpiUtilDependency = project.dependencies.create("edu.wpi.first.wpilib:wpiutil:+:desktop@zip")
|
|
||||||
def desktopWpiUtilConfig = project.configurations.detachedConfiguration(desktopWpiUtilDependency)
|
|
||||||
desktopWpiUtilConfig.setTransitive(false)
|
|
||||||
wpiUtil = desktopWpiUtilConfig.files[0].canonicalFile
|
|
||||||
}
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
copy {
|
|
||||||
from wpiUtil
|
|
||||||
rename 'wpiutil(.+)', 'wpiutil-desk.zip'
|
|
||||||
into depFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def wpiUtilUnzipLocation = "$buildDir/wpiutil"
|
|
||||||
|
|
||||||
// Create a task that will unzip the wpiutil files into a temporary build directory
|
|
||||||
task unzipWpiUtil(type: Copy) {
|
|
||||||
description = 'Unzips the wpiutil maven dependency so that the include files and libraries can be used'
|
|
||||||
group = 'WPILib'
|
|
||||||
dependsOn downloadArmWpiUtil
|
|
||||||
|
|
||||||
if (project.hasProperty('makeSim')) {
|
|
||||||
dependsOn downloadDesktopWpiUtil
|
|
||||||
from zipTree(downloadDesktopWpiUtil.outputs.files.singleFile)
|
|
||||||
}
|
|
||||||
from zipTree(downloadArmWpiUtil.outputs.files.singleFile)
|
|
||||||
into wpiUtilUnzipLocation
|
|
||||||
}
|
|
||||||
|
|
||||||
task clean(type: Delete) {
|
|
||||||
description = "Deletes the build directory"
|
|
||||||
group = "Build"
|
|
||||||
delete buildDir
|
|
||||||
}
|
|
||||||
|
|
||||||
subprojects {
|
|
||||||
ext.defineWpiUtilProperties = {
|
|
||||||
ext.wpiUtil = wpiUtilUnzipLocation
|
|
||||||
ext.wpiUtilInclude = "$wpiUtilUnzipLocation/include"
|
|
||||||
ext.wpiUtilLibArmLocation = "$wpiUtilUnzipLocation/Linux/arm"
|
|
||||||
if (project.hasProperty('makeSim')) {
|
|
||||||
ext.wpiUtilLibDesktopLocation = "$wpiUtilUnzipLocation/Linux/amd64"
|
|
||||||
}
|
|
||||||
ext.wpiUtilSharedLib = "$wpiUtilLibArmLocation/libwpiutil.so"
|
|
||||||
ext.wpiUtilSharedLibDebug = "$wpiUtilLibArmLocation/libwpiutil.so.debug"
|
|
||||||
ext.wpiUtilStaticLib = "$wpiUtilLibArmLocation/libwpiutil.a"
|
|
||||||
|
|
||||||
ext.addWpiUtilLibraryLinks = { compileTask, linker, targetPlatform ->
|
|
||||||
compileTask.dependsOn project(':').unzipWpiUtil
|
|
||||||
String architecture = targetPlatform.architecture
|
|
||||||
if (architecture.contains('arm')) {
|
|
||||||
linker.args wpiUtilSharedLib
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ext.addStaticWpiUtilLibraryLinks = { compileTask, linker, targetPlatform ->
|
|
||||||
compileTask.dependsOn project(':').unzipWpiUtil
|
|
||||||
String architecture = targetPlatform.architecture
|
|
||||||
if (architecture.contains('arm')) {
|
|
||||||
linker.args wpiUtilStaticLib
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This defines a project property that projects depending on network tables can use to setup that dependency.
|
|
||||||
ext.defineNetworkTablesProperties = {
|
|
||||||
ext.netTables = netTablesUnzipLocation
|
|
||||||
ext.netTablesInclude = "$netTablesUnzipLocation/include"
|
|
||||||
ext.netLibArmLocation = "$netTablesUnzipLocation/Linux/arm"
|
|
||||||
if (project.hasProperty('makeSim')) {
|
|
||||||
ext.netLibDesktopLocation = "$netTablesUnzipLocation/Linux/amd64"
|
|
||||||
}
|
|
||||||
ext.netSharedLib = "$netLibArmLocation/libntcore.so"
|
|
||||||
ext.netSharedLibDebug = "$netLibArmLocation/libntcore.so.debug"
|
|
||||||
ext.netStaticLib = "$netLibArmLocation/libntcore.a"
|
|
||||||
|
|
||||||
ext.addNetworkTablesLibraryLinks = { compileTask, linker, targetPlatform ->
|
|
||||||
compileTask.dependsOn project(':').unzipNetworkTables
|
|
||||||
String architecture = targetPlatform.architecture
|
|
||||||
if (architecture.contains('arm')) {
|
|
||||||
linker.args netSharedLib
|
|
||||||
}
|
|
||||||
addWpiUtilLibraryLinks(compileTask, linker, targetPlatform)
|
|
||||||
}
|
|
||||||
|
|
||||||
ext.addStaticNetworkTablesLibraryLinks = { compileTask, linker, targetPlatform ->
|
|
||||||
compileTask.dependsOn project(':').unzipNetworkTables
|
|
||||||
String architecture = targetPlatform.architecture
|
|
||||||
if (architecture.contains('arm')) {
|
|
||||||
linker.args netStaticLib
|
|
||||||
}
|
|
||||||
addStaticWpiUtilLibraryLinks(compileTask, linker, targetPlatform)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plugins.withType(CppPlugin).whenPluginAdded {
|
|
||||||
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
|
|
||||||
// If this ever changes, the prefix will need to be changed here
|
|
||||||
def compilerPrefix = 'arm-frc-linux-gnueabi-'
|
|
||||||
model {
|
|
||||||
buildTypes {
|
|
||||||
debug
|
|
||||||
}
|
|
||||||
// Adds a custom toolchain for our compiler prefix and options
|
|
||||||
toolChains {
|
|
||||||
gcc(Gcc) {
|
|
||||||
target('arm') {
|
|
||||||
cppCompiler.executable = compilerPrefix + cppCompiler.executable
|
|
||||||
linker.executable = compilerPrefix + linker.executable
|
|
||||||
assembler.executable = compilerPrefix + assembler.executable
|
|
||||||
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
|
|
||||||
// arm, and doesn't understand this flag, so it is removed from both
|
|
||||||
cppCompiler.withArguments { args ->
|
|
||||||
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
|
|
||||||
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-Og' << '-g3' << '-rdynamic'
|
|
||||||
//TODO: When the compiler allows us to actually call deprecated functions from within
|
|
||||||
// deprecated function, remove this line (this will cause calling deprecated functions
|
|
||||||
// to be treated as a warning rather than an error).
|
|
||||||
args << '-Wno-error=deprecated-declarations'
|
|
||||||
args.remove('-m32')
|
|
||||||
}
|
|
||||||
linker.withArguments { args ->
|
|
||||||
args << '-rdynamic'
|
|
||||||
args.remove('-m32')
|
|
||||||
}
|
|
||||||
staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Workaround for OS X. Macs for some reason want to use Xcode's gcc
|
|
||||||
// (which just wraps Clang), so we have to explicitly make it so
|
|
||||||
// that trying to compile with Clang will call gcc instead
|
|
||||||
macGcc(Clang) {
|
|
||||||
target('arm') {
|
|
||||||
cppCompiler.executable = compilerPrefix + 'g++'
|
|
||||||
linker.executable = compilerPrefix + 'g++'
|
|
||||||
assembler.executable = compilerPrefix + 'gcc'
|
|
||||||
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
|
|
||||||
// arm, and doesn't understand this flag, so it is removed from both
|
|
||||||
cppCompiler.withArguments { args ->
|
|
||||||
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
|
|
||||||
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-Og' << '-g3' << '-rdynamic'
|
|
||||||
//TODO: When the compiler allows us to actually call deprecated functions from within
|
|
||||||
// deprecated function, remove this line (this will cause calling deprecated functions
|
|
||||||
// to be treated as a warning rather than an error).
|
|
||||||
args << '-Wno-error=deprecated-declarations'
|
|
||||||
args.remove('-m32')
|
|
||||||
}
|
|
||||||
linker.withArguments { args ->
|
|
||||||
args << '-rdynamic'
|
|
||||||
args.remove('-m32')
|
|
||||||
}
|
|
||||||
staticLibArchiver.executable = compilerPrefix + 'ar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The only platform is arm linux
|
|
||||||
platforms {
|
|
||||||
arm {
|
|
||||||
architecture 'arm'
|
|
||||||
operatingSystem 'linux'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This task adds the appropriate linker flags for the NI libraries
|
|
||||||
ext.addNiLibraryLinks = { linker, targetPlatform ->
|
|
||||||
String architecture = targetPlatform.architecture
|
|
||||||
if (architecture.contains('arm')){
|
|
||||||
linker.args << '-L' + niLibraryPath
|
|
||||||
linker.args niLibrary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This task sets up the shared libraries to be stripped
|
|
||||||
ext.debugStripSetup = { project->
|
|
||||||
if (!project.hasProperty('debug')) {
|
|
||||||
project.tasks.whenObjectAdded { task ->
|
|
||||||
def name = task.name.toLowerCase()
|
|
||||||
if (name.contains('link') && name.contains('sharedlibrary')) {
|
|
||||||
def library = task.outputFile.absolutePath
|
|
||||||
def debugLibrary = task.outputFile.absolutePath + ".debug"
|
|
||||||
task.doLast {
|
|
||||||
exec { commandLine "${compilerPrefix}objcopy", '--only-keep-debug', library, debugLibrary }
|
|
||||||
exec { commandLine "${compilerPrefix}strip", '-g', library }
|
|
||||||
exec { commandLine "${compilerPrefix}objcopy", "--add-gnu-debuglink=$debugLibrary", library }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
86
gmock/CMakeLists.txt
Normal file
86
gmock/CMakeLists.txt
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
########################################################################
|
||||||
|
# CMake build script for Google Mock.
|
||||||
|
#
|
||||||
|
# To run the tests for Google Mock itself on Linux, use 'make test' or
|
||||||
|
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||||
|
# For more options, run 'ctest --help'.
|
||||||
|
|
||||||
|
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
|
||||||
|
# make it prominent in the GUI.
|
||||||
|
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
|
||||||
|
|
||||||
|
# A directory to find Google Test sources.
|
||||||
|
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt")
|
||||||
|
set(gtest_dir gtest)
|
||||||
|
else()
|
||||||
|
set(gtest_dir ../gtest)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||||
|
include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL)
|
||||||
|
|
||||||
|
if (COMMAND pre_project_set_up_hermetic_build)
|
||||||
|
# Google Test also calls hermetic setup functions from add_subdirectory,
|
||||||
|
# although its changes will not affect things at the current scope.
|
||||||
|
pre_project_set_up_hermetic_build()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#
|
||||||
|
# Project-wide settings
|
||||||
|
|
||||||
|
# Name of the project.
|
||||||
|
#
|
||||||
|
# CMake files in this project can refer to the root source directory
|
||||||
|
# as ${gmock_SOURCE_DIR} and to the root binary directory as
|
||||||
|
# ${gmock_BINARY_DIR}.
|
||||||
|
# Language "C" is required for find_package(Threads).
|
||||||
|
project(gmock CXX C)
|
||||||
|
cmake_minimum_required(VERSION 2.6.2)
|
||||||
|
|
||||||
|
if (COMMAND set_up_hermetic_build)
|
||||||
|
set_up_hermetic_build()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-format-nonliteral")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Instructs CMake to process Google Test's CMakeLists.txt and add its
|
||||||
|
# targets to the current scope. We are placing Google Test's binary
|
||||||
|
# directory in a subdirectory of our own as VC compilation may break
|
||||||
|
# if they are the same (the default).
|
||||||
|
add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/gtest")
|
||||||
|
|
||||||
|
# Although Google Test's CMakeLists.txt calls this function, the
|
||||||
|
# changes there don't affect the current scope. Therefore we have to
|
||||||
|
# call it again here.
|
||||||
|
config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake
|
||||||
|
|
||||||
|
# Adds Google Mock's and Google Test's header directories to the search path.
|
||||||
|
include_directories("${gmock_SOURCE_DIR}/include"
|
||||||
|
"${gmock_SOURCE_DIR}"
|
||||||
|
"${gtest_SOURCE_DIR}/include"
|
||||||
|
# This directory is needed to build directly from Google
|
||||||
|
# Test sources.
|
||||||
|
"${gtest_SOURCE_DIR}")
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#
|
||||||
|
# Defines the gmock & gmock_main libraries. User tests should link
|
||||||
|
# with one of them.
|
||||||
|
|
||||||
|
# Google Mock libraries. We build them using more strict warnings than what
|
||||||
|
# are used for other targets, to ensure that Google Mock can be compiled by
|
||||||
|
# a user aggressive about warnings.
|
||||||
|
cxx_library(gmock
|
||||||
|
"${cxx_strict}"
|
||||||
|
"${gtest_dir}/src/gtest-all.cc"
|
||||||
|
src/gmock-all.cc)
|
||||||
|
|
||||||
|
cxx_library(gmock_main
|
||||||
|
"${cxx_strict}"
|
||||||
|
"${gtest_dir}/src/gtest-all.cc"
|
||||||
|
src/gmock-all.cc
|
||||||
|
src/gmock_main.cc)
|
||||||
|
|
||||||
28
gmock/LICENSE
Normal file
28
gmock/LICENSE
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
Copyright 2008, Google Inc.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
44
gmock/build.gradle
Normal file
44
gmock/build.gradle
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
|
||||||
|
if (!project.hasProperty('onlyAthena')) {
|
||||||
|
apply plugin: 'cpp'
|
||||||
|
apply plugin: 'visual-studio'
|
||||||
|
apply plugin: 'edu.wpi.first.NativeUtils'
|
||||||
|
|
||||||
|
ext.gmockProject = true
|
||||||
|
|
||||||
|
apply from: '../config.gradle'
|
||||||
|
|
||||||
|
ext.addGmockToLinker = { binary->
|
||||||
|
binary.lib project: ':gmock', library: 'gmock', linkage: 'static'
|
||||||
|
}
|
||||||
|
|
||||||
|
model {
|
||||||
|
components {
|
||||||
|
gmock(NativeLibrarySpec) {
|
||||||
|
sources {
|
||||||
|
cpp {
|
||||||
|
source {
|
||||||
|
srcDirs = ['src', 'gtest/src']
|
||||||
|
includes = ['*-all.cc']
|
||||||
|
}
|
||||||
|
exportedHeaders {
|
||||||
|
srcDirs = ['include', 'gtest/include', '.', 'gtest']
|
||||||
|
includes = ['**/*.h', '**/*.cc']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binaries.all {
|
||||||
|
if (toolChain in VisualCpp) {
|
||||||
|
cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1'
|
||||||
|
} else {
|
||||||
|
cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-pthread', '-fPIC'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binaries.withType(SharedLibraryBinarySpec) {
|
||||||
|
buildable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
gmock/gtest/CMakeLists.txt
Normal file
69
gmock/gtest/CMakeLists.txt
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
########################################################################
|
||||||
|
# CMake build script for Google Test.
|
||||||
|
#
|
||||||
|
# To run the tests for Google Test itself on Linux, use 'make test' or
|
||||||
|
# ctest. You can select which tests to run using 'ctest -R regex'.
|
||||||
|
# For more options, run 'ctest --help'.
|
||||||
|
|
||||||
|
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
|
||||||
|
# make it prominent in the GUI.
|
||||||
|
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
|
||||||
|
|
||||||
|
# When other libraries are using a shared version of runtime libraries,
|
||||||
|
# Google Test also has to use one.
|
||||||
|
option(
|
||||||
|
gtest_force_shared_crt
|
||||||
|
"Use shared (DLL) run-time lib even when Google Test is built as static lib."
|
||||||
|
OFF)
|
||||||
|
|
||||||
|
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
|
||||||
|
|
||||||
|
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
|
||||||
|
include(cmake/hermetic_build.cmake OPTIONAL)
|
||||||
|
|
||||||
|
if (COMMAND pre_project_set_up_hermetic_build)
|
||||||
|
pre_project_set_up_hermetic_build()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#
|
||||||
|
# Project-wide settings
|
||||||
|
|
||||||
|
# Name of the project.
|
||||||
|
#
|
||||||
|
# CMake files in this project can refer to the root source directory
|
||||||
|
# as ${gtest_SOURCE_DIR} and to the root binary directory as
|
||||||
|
# ${gtest_BINARY_DIR}.
|
||||||
|
# Language "C" is required for find_package(Threads).
|
||||||
|
project(gtest CXX C)
|
||||||
|
cmake_minimum_required(VERSION 2.6.2)
|
||||||
|
|
||||||
|
if (COMMAND set_up_hermetic_build)
|
||||||
|
set_up_hermetic_build()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Define helper functions and macros used by Google Test.
|
||||||
|
include(cmake/internal_utils.cmake)
|
||||||
|
|
||||||
|
config_compiler_and_linker() # Defined in internal_utils.cmake.
|
||||||
|
|
||||||
|
# Where Google Test's .h files can be found.
|
||||||
|
include_directories(
|
||||||
|
${gtest_SOURCE_DIR}/include
|
||||||
|
${gtest_SOURCE_DIR})
|
||||||
|
|
||||||
|
# Where Google Test's libraries can be found.
|
||||||
|
link_directories(${gtest_BINARY_DIR}/src)
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#
|
||||||
|
# Defines the gtest & gtest_main libraries. User tests should link
|
||||||
|
# with one of them.
|
||||||
|
|
||||||
|
# Google Test libraries. We build them using more strict warnings than what
|
||||||
|
# are used for other targets, to ensure that gtest can be compiled by a user
|
||||||
|
# aggressive about warnings.
|
||||||
|
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
|
||||||
|
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
|
||||||
|
target_link_libraries(gtest_main gtest)
|
||||||
|
|
||||||
28
gmock/gtest/LICENSE
Normal file
28
gmock/gtest/LICENSE
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
Copyright 2008, Google Inc.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
206
gmock/gtest/cmake/internal_utils.cmake
Normal file
206
gmock/gtest/cmake/internal_utils.cmake
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
# Defines functions and macros useful for building Google Test and
|
||||||
|
# Google Mock.
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
#
|
||||||
|
# - This file will be run twice when building Google Mock (once via
|
||||||
|
# Google Test's CMakeLists.txt, and once via Google Mock's).
|
||||||
|
# Therefore it shouldn't have any side effects other than defining
|
||||||
|
# the functions and macros.
|
||||||
|
#
|
||||||
|
# - The functions/macros defined in this file may depend on Google
|
||||||
|
# Test and Google Mock's option() definitions, and thus must be
|
||||||
|
# called *after* the options have been defined.
|
||||||
|
|
||||||
|
# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.
|
||||||
|
#
|
||||||
|
# This must be a macro(), as inside a function string() can only
|
||||||
|
# update variables in the function scope.
|
||||||
|
macro(fix_default_compiler_settings_)
|
||||||
|
if (MSVC)
|
||||||
|
# For MSVC, CMake sets certain flags to defaults we want to override.
|
||||||
|
# This replacement code is taken from sample in the CMake Wiki at
|
||||||
|
# http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace.
|
||||||
|
foreach (flag_var
|
||||||
|
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||||
|
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||||
|
if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
|
||||||
|
# When Google Test is built as a shared library, it should also use
|
||||||
|
# shared runtime libraries. Otherwise, it may end up with multiple
|
||||||
|
# copies of runtime library data in different modules, resulting in
|
||||||
|
# hard-to-find crashes. When it is built as a static library, it is
|
||||||
|
# preferable to use CRT as static libraries, as we don't have to rely
|
||||||
|
# on CRT DLLs being available. CMake always defaults to using shared
|
||||||
|
# CRT libraries, so we override that default here.
|
||||||
|
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# We prefer more strict warning checking for building Google Test.
|
||||||
|
# Replaces /W3 with /W4 in defaults.
|
||||||
|
string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Defines the compiler/linker flags used to build Google Test and
|
||||||
|
# Google Mock. You can tweak these definitions to suit your need. A
|
||||||
|
# variable's value is empty before it's explicitly assigned to.
|
||||||
|
macro(config_compiler_and_linker)
|
||||||
|
if (NOT gtest_disable_pthreads)
|
||||||
|
# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
|
||||||
|
find_package(Threads)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
fix_default_compiler_settings_()
|
||||||
|
if (MSVC)
|
||||||
|
# Newlines inside flags variables break CMake's NMake generator.
|
||||||
|
# TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.
|
||||||
|
set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi")
|
||||||
|
if (MSVC_VERSION LESS 1400)
|
||||||
|
# Suppress spurious warnings MSVC 7.1 sometimes issues.
|
||||||
|
# Forcing value to bool.
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -wd4800")
|
||||||
|
# Copy constructor and assignment operator could not be generated.
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512")
|
||||||
|
# Compatibility warnings not applicable to Google Test.
|
||||||
|
# Resolved overload was found by argument-dependent lookup.
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -wd4675")
|
||||||
|
endif()
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
|
||||||
|
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
|
||||||
|
set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
|
||||||
|
set(cxx_no_rtti_flags "-GR-")
|
||||||
|
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
set(cxx_base_flags "-Wall -Wshadow")
|
||||||
|
set(cxx_exception_flags "-fexceptions")
|
||||||
|
set(cxx_no_exception_flags "-fno-exceptions")
|
||||||
|
# Until version 4.3.2, GCC doesn't define a macro to indicate
|
||||||
|
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||||
|
# explicitly.
|
||||||
|
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
|
||||||
|
set(cxx_strict_flags
|
||||||
|
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
|
||||||
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
|
||||||
|
set(cxx_exception_flags "-features=except")
|
||||||
|
# Sun Pro doesn't provide macros to indicate whether exceptions and
|
||||||
|
# RTTI are enabled, so we define GTEST_HAS_* explicitly.
|
||||||
|
set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
|
||||||
|
set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
|
||||||
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
|
||||||
|
CMAKE_CXX_COMPILER_ID STREQUAL "XL")
|
||||||
|
# CMake 2.8 changes Visual Age's compiler ID to "XL".
|
||||||
|
set(cxx_exception_flags "-qeh")
|
||||||
|
set(cxx_no_exception_flags "-qnoeh")
|
||||||
|
# Until version 9.0, Visual Age doesn't define a macro to indicate
|
||||||
|
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||||
|
# explicitly.
|
||||||
|
set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
|
||||||
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP")
|
||||||
|
set(cxx_base_flags "-AA -mt")
|
||||||
|
set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1")
|
||||||
|
set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0")
|
||||||
|
# RTTI can not be disabled in HP aCC compiler.
|
||||||
|
set(cxx_no_rtti_flags "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed.
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1")
|
||||||
|
else()
|
||||||
|
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# For building gtest's own tests and samples.
|
||||||
|
set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}")
|
||||||
|
set(cxx_no_exception
|
||||||
|
"${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
|
||||||
|
set(cxx_default "${cxx_exception}")
|
||||||
|
set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
|
||||||
|
set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1")
|
||||||
|
|
||||||
|
# For building the gtest libraries.
|
||||||
|
set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Defines the gtest & gtest_main libraries. User tests should link
|
||||||
|
# with one of them.
|
||||||
|
function(cxx_library_with_type name type cxx_flags)
|
||||||
|
# type can be either STATIC or SHARED to denote a static or shared library.
|
||||||
|
# ARGN refers to additional arguments after 'cxx_flags'.
|
||||||
|
add_library(${name} ${type} ${ARGN})
|
||||||
|
set_target_properties(${name}
|
||||||
|
PROPERTIES
|
||||||
|
COMPILE_FLAGS "${cxx_flags}")
|
||||||
|
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
|
||||||
|
set_target_properties(${name}
|
||||||
|
PROPERTIES
|
||||||
|
COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
|
||||||
|
endif()
|
||||||
|
if (CMAKE_USE_PTHREADS_INIT)
|
||||||
|
target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#
|
||||||
|
# Helper functions for creating build targets.
|
||||||
|
|
||||||
|
function(cxx_shared_library name cxx_flags)
|
||||||
|
cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(cxx_library name cxx_flags)
|
||||||
|
cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# cxx_executable_with_flags(name cxx_flags libs srcs...)
|
||||||
|
#
|
||||||
|
# creates a named C++ executable that depends on the given libraries and
|
||||||
|
# is built from the given source files with the given compiler flags.
|
||||||
|
function(cxx_executable_with_flags name cxx_flags libs)
|
||||||
|
add_executable(${name} ${ARGN})
|
||||||
|
if (cxx_flags)
|
||||||
|
set_target_properties(${name}
|
||||||
|
PROPERTIES
|
||||||
|
COMPILE_FLAGS "${cxx_flags}")
|
||||||
|
endif()
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
set_target_properties(${name}
|
||||||
|
PROPERTIES
|
||||||
|
COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
|
||||||
|
endif()
|
||||||
|
# To support mixing linking in static and dynamic libraries, link each
|
||||||
|
# library in with an extra call to target_link_libraries.
|
||||||
|
foreach (lib "${libs}")
|
||||||
|
target_link_libraries(${name} ${lib})
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# cxx_executable(name dir lib srcs...)
|
||||||
|
#
|
||||||
|
# creates a named target that depends on the given libs and is built
|
||||||
|
# from the given source files. dir/name.cc is implicitly included in
|
||||||
|
# the source file list.
|
||||||
|
function(cxx_executable name dir libs)
|
||||||
|
cxx_executable_with_flags(
|
||||||
|
${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# cxx_test_with_flags(name cxx_flags libs srcs...)
|
||||||
|
#
|
||||||
|
# creates a named C++ test that depends on the given libs and is built
|
||||||
|
# from the given source files with the given compiler flags.
|
||||||
|
function(cxx_test_with_flags name cxx_flags libs)
|
||||||
|
cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN})
|
||||||
|
add_test(${name} ${name})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# cxx_test(name libs srcs...)
|
||||||
|
#
|
||||||
|
# creates a named test target that depends on the given libs and is
|
||||||
|
# built from the given source files. Unlike cxx_test_with_flags,
|
||||||
|
# test/name.cc is already implicitly included in the source file list.
|
||||||
|
function(cxx_test name libs)
|
||||||
|
cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
|
||||||
|
"test/${name}.cc" ${ARGN})
|
||||||
|
endfunction()
|
||||||
@@ -103,10 +103,6 @@
|
|||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
#include "gtest/internal/gtest-internal.h"
|
#include "gtest/internal/gtest-internal.h"
|
||||||
|
|
||||||
#if GTEST_HAS_STD_TUPLE_
|
|
||||||
# include <tuple>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
// Definitions in the 'internal' and 'internal2' name spaces are
|
// Definitions in the 'internal' and 'internal2' name spaces are
|
||||||
@@ -484,16 +480,14 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
|||||||
}
|
}
|
||||||
#endif // GTEST_HAS_STD_WSTRING
|
#endif // GTEST_HAS_STD_WSTRING
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
#if GTEST_HAS_TR1_TUPLE
|
||||||
|
// Overload for ::std::tr1::tuple. Needed for printing function arguments,
|
||||||
|
// which are packed as tuples.
|
||||||
|
|
||||||
// Helper function for printing a tuple. T must be instantiated with
|
// Helper function for printing a tuple. T must be instantiated with
|
||||||
// a tuple type.
|
// a tuple type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PrintTupleTo(const T& t, ::std::ostream* os);
|
void PrintTupleTo(const T& t, ::std::ostream* os);
|
||||||
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE
|
|
||||||
// Overload for ::std::tr1::tuple. Needed for printing function arguments,
|
|
||||||
// which are packed as tuples.
|
|
||||||
|
|
||||||
// Overloaded PrintTo() for tuples of various arities. We support
|
// Overloaded PrintTo() for tuples of various arities. We support
|
||||||
// tuples of up-to 10 fields. The following implementation works
|
// tuples of up-to 10 fields. The following implementation works
|
||||||
@@ -567,13 +561,6 @@ void PrintTo(
|
|||||||
}
|
}
|
||||||
#endif // GTEST_HAS_TR1_TUPLE
|
#endif // GTEST_HAS_TR1_TUPLE
|
||||||
|
|
||||||
#if GTEST_HAS_STD_TUPLE_
|
|
||||||
template <typename... Types>
|
|
||||||
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
|
|
||||||
PrintTupleTo(t, os);
|
|
||||||
}
|
|
||||||
#endif // GTEST_HAS_STD_TUPLE_
|
|
||||||
|
|
||||||
// Overload for std::pair.
|
// Overload for std::pair.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
||||||
@@ -593,7 +580,10 @@ class UniversalPrinter {
|
|||||||
public:
|
public:
|
||||||
// MSVC warns about adding const to a function type, so we want to
|
// MSVC warns about adding const to a function type, so we want to
|
||||||
// disable the warning.
|
// disable the warning.
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4180) // Temporarily disables warning 4180.
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
// Note: we deliberately don't call this PrintTo(), as that name
|
// Note: we deliberately don't call this PrintTo(), as that name
|
||||||
// conflicts with ::testing::internal::PrintTo in the body of the
|
// conflicts with ::testing::internal::PrintTo in the body of the
|
||||||
@@ -610,7 +600,9 @@ class UniversalPrinter {
|
|||||||
PrintTo(value, os);
|
PrintTo(value, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
#endif // _MSC_VER
|
||||||
};
|
};
|
||||||
|
|
||||||
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||||
@@ -662,7 +654,10 @@ class UniversalPrinter<T&> {
|
|||||||
public:
|
public:
|
||||||
// MSVC warns about adding const to a function type, so we want to
|
// MSVC warns about adding const to a function type, so we want to
|
||||||
// disable the warning.
|
// disable the warning.
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4180) // Temporarily disables warning 4180.
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
static void Print(const T& value, ::std::ostream* os) {
|
static void Print(const T& value, ::std::ostream* os) {
|
||||||
// Prints the address of the value. We use reinterpret_cast here
|
// Prints the address of the value. We use reinterpret_cast here
|
||||||
@@ -673,7 +668,9 @@ class UniversalPrinter<T&> {
|
|||||||
UniversalPrint(value, os);
|
UniversalPrint(value, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
#endif // _MSC_VER
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prints a value tersely: for a reference type, the referenced value
|
// Prints a value tersely: for a reference type, the referenced value
|
||||||
@@ -759,65 +756,16 @@ void UniversalPrint(const T& value, ::std::ostream* os) {
|
|||||||
UniversalPrinter<T1>::Print(value, os);
|
UniversalPrinter<T1>::Print(value, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_TR1_TUPLE
|
||||||
typedef ::std::vector<string> Strings;
|
typedef ::std::vector<string> Strings;
|
||||||
|
|
||||||
// TuplePolicy<TupleT> must provide:
|
|
||||||
// - tuple_size
|
|
||||||
// size of tuple TupleT.
|
|
||||||
// - get<size_t I>(const TupleT& t)
|
|
||||||
// static function extracting element I of tuple TupleT.
|
|
||||||
// - tuple_element<size_t I>::type
|
|
||||||
// type of element I of tuple TupleT.
|
|
||||||
template <typename TupleT>
|
|
||||||
struct TuplePolicy;
|
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE
|
|
||||||
template <typename TupleT>
|
|
||||||
struct TuplePolicy {
|
|
||||||
typedef TupleT Tuple;
|
|
||||||
static const size_t tuple_size = ::std::tr1::tuple_size<Tuple>::value;
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
struct tuple_element : ::std::tr1::tuple_element<I, Tuple> {};
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
static typename AddReference<
|
|
||||||
const typename ::std::tr1::tuple_element<I, Tuple>::type>::type get(
|
|
||||||
const Tuple& tuple) {
|
|
||||||
return ::std::tr1::get<I>(tuple);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <typename TupleT>
|
|
||||||
const size_t TuplePolicy<TupleT>::tuple_size;
|
|
||||||
#endif // GTEST_HAS_TR1_TUPLE
|
|
||||||
|
|
||||||
#if GTEST_HAS_STD_TUPLE_
|
|
||||||
template <typename... Types>
|
|
||||||
struct TuplePolicy< ::std::tuple<Types...> > {
|
|
||||||
typedef ::std::tuple<Types...> Tuple;
|
|
||||||
static const size_t tuple_size = ::std::tuple_size<Tuple>::value;
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
struct tuple_element : ::std::tuple_element<I, Tuple> {};
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
static const typename ::std::tuple_element<I, Tuple>::type& get(
|
|
||||||
const Tuple& tuple) {
|
|
||||||
return ::std::get<I>(tuple);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <typename... Types>
|
|
||||||
const size_t TuplePolicy< ::std::tuple<Types...> >::tuple_size;
|
|
||||||
#endif // GTEST_HAS_STD_TUPLE_
|
|
||||||
|
|
||||||
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
|
||||||
// This helper template allows PrintTo() for tuples and
|
// This helper template allows PrintTo() for tuples and
|
||||||
// UniversalTersePrintTupleFieldsToStrings() to be defined by
|
// UniversalTersePrintTupleFieldsToStrings() to be defined by
|
||||||
// induction on the number of tuple fields. The idea is that
|
// induction on the number of tuple fields. The idea is that
|
||||||
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
|
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
|
||||||
// fields in tuple t, and can be defined in terms of
|
// fields in tuple t, and can be defined in terms of
|
||||||
// TuplePrefixPrinter<N - 1>.
|
// TuplePrefixPrinter<N - 1>.
|
||||||
//
|
|
||||||
// The inductive case.
|
// The inductive case.
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
struct TuplePrefixPrinter {
|
struct TuplePrefixPrinter {
|
||||||
@@ -825,14 +773,9 @@ struct TuplePrefixPrinter {
|
|||||||
template <typename Tuple>
|
template <typename Tuple>
|
||||||
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||||
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
|
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
|
||||||
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
*os << ", ";
|
||||||
if (N > 1) {
|
UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
|
||||||
GTEST_INTENTIONAL_CONST_COND_POP_()
|
::Print(::std::tr1::get<N - 1>(t), os);
|
||||||
*os << ", ";
|
|
||||||
}
|
|
||||||
UniversalPrinter<
|
|
||||||
typename TuplePolicy<Tuple>::template tuple_element<N - 1>::type>
|
|
||||||
::Print(TuplePolicy<Tuple>::template get<N - 1>(t), os);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tersely prints the first N fields of a tuple to a string vector,
|
// Tersely prints the first N fields of a tuple to a string vector,
|
||||||
@@ -841,12 +784,12 @@ struct TuplePrefixPrinter {
|
|||||||
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
|
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
|
||||||
TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
|
TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
|
||||||
::std::stringstream ss;
|
::std::stringstream ss;
|
||||||
UniversalTersePrint(TuplePolicy<Tuple>::template get<N - 1>(t), &ss);
|
UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss);
|
||||||
strings->push_back(ss.str());
|
strings->push_back(ss.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base case.
|
// Base cases.
|
||||||
template <>
|
template <>
|
||||||
struct TuplePrefixPrinter<0> {
|
struct TuplePrefixPrinter<0> {
|
||||||
template <typename Tuple>
|
template <typename Tuple>
|
||||||
@@ -855,13 +798,34 @@ struct TuplePrefixPrinter<0> {
|
|||||||
template <typename Tuple>
|
template <typename Tuple>
|
||||||
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
|
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
|
||||||
};
|
};
|
||||||
|
// We have to specialize the entire TuplePrefixPrinter<> class
|
||||||
|
// template here, even though the definition of
|
||||||
|
// TersePrintPrefixToStrings() is the same as the generic version, as
|
||||||
|
// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't
|
||||||
|
// support specializing a method template of a class template.
|
||||||
|
template <>
|
||||||
|
struct TuplePrefixPrinter<1> {
|
||||||
|
template <typename Tuple>
|
||||||
|
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||||
|
UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
|
||||||
|
Print(::std::tr1::get<0>(t), os);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function for printing a tuple.
|
template <typename Tuple>
|
||||||
// Tuple must be either std::tr1::tuple or std::tuple type.
|
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
|
||||||
template <typename Tuple>
|
::std::stringstream ss;
|
||||||
void PrintTupleTo(const Tuple& t, ::std::ostream* os) {
|
UniversalTersePrint(::std::tr1::get<0>(t), &ss);
|
||||||
|
strings->push_back(ss.str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function for printing a tuple. T must be instantiated with
|
||||||
|
// a tuple type.
|
||||||
|
template <typename T>
|
||||||
|
void PrintTupleTo(const T& t, ::std::ostream* os) {
|
||||||
*os << "(";
|
*os << "(";
|
||||||
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::PrintPrefixTo(t, os);
|
TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>::
|
||||||
|
PrintPrefixTo(t, os);
|
||||||
*os << ")";
|
*os << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,11 +835,11 @@ void PrintTupleTo(const Tuple& t, ::std::ostream* os) {
|
|||||||
template <typename Tuple>
|
template <typename Tuple>
|
||||||
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
||||||
Strings result;
|
Strings result;
|
||||||
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::
|
TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
|
||||||
TersePrintPrefixToStrings(value, &result);
|
TersePrintPrefixToStrings(value, &result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
#endif // GTEST_HAS_TR1_TUPLE
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
@@ -258,31 +258,8 @@ class GTEST_API_ AssertionResult {
|
|||||||
// Copy constructor.
|
// Copy constructor.
|
||||||
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
||||||
AssertionResult(const AssertionResult& other);
|
AssertionResult(const AssertionResult& other);
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
|
|
||||||
|
|
||||||
// Used in the EXPECT_TRUE/FALSE(bool_expression).
|
// Used in the EXPECT_TRUE/FALSE(bool_expression).
|
||||||
//
|
explicit AssertionResult(bool success) : success_(success) {}
|
||||||
// T must be contextually convertible to bool.
|
|
||||||
//
|
|
||||||
// The second parameter prevents this overload from being considered if
|
|
||||||
// the argument is implicitly convertible to AssertionResult. In that case
|
|
||||||
// we want AssertionResult's copy constructor to be used.
|
|
||||||
template <typename T>
|
|
||||||
explicit AssertionResult(
|
|
||||||
const T& success,
|
|
||||||
typename internal::EnableIf<
|
|
||||||
!internal::ImplicitlyConvertible<T, AssertionResult>::value>::type*
|
|
||||||
/*enabler*/ = NULL)
|
|
||||||
: success_(success) {}
|
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
||||||
|
|
||||||
// Assignment operator.
|
|
||||||
AssertionResult& operator=(AssertionResult other) {
|
|
||||||
swap(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true iff the assertion succeeded.
|
// Returns true iff the assertion succeeded.
|
||||||
operator bool() const { return success_; } // NOLINT
|
operator bool() const { return success_; } // NOLINT
|
||||||
@@ -323,9 +300,6 @@ class GTEST_API_ AssertionResult {
|
|||||||
message_->append(a_message.GetString().c_str());
|
message_->append(a_message.GetString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap the contents of this AssertionResult with other.
|
|
||||||
void swap(AssertionResult& other);
|
|
||||||
|
|
||||||
// Stores result of the assertion predicate.
|
// Stores result of the assertion predicate.
|
||||||
bool success_;
|
bool success_;
|
||||||
// Stores the message describing the condition in case the expectation
|
// Stores the message describing the condition in case the expectation
|
||||||
@@ -333,6 +307,8 @@ class GTEST_API_ AssertionResult {
|
|||||||
// Referenced via a pointer to avoid taking too much stack frame space
|
// Referenced via a pointer to avoid taking too much stack frame space
|
||||||
// with test assertions.
|
// with test assertions.
|
||||||
internal::scoped_ptr< ::std::string> message_;
|
internal::scoped_ptr< ::std::string> message_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(AssertionResult);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Makes a successful assertion result.
|
// Makes a successful assertion result.
|
||||||
@@ -1463,11 +1439,19 @@ AssertionResult CmpHelperEQ(const char* expected_expression,
|
|||||||
const char* actual_expression,
|
const char* actual_expression,
|
||||||
const T1& expected,
|
const T1& expected,
|
||||||
const T2& actual) {
|
const T2& actual) {
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */)
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4389) // Temporarily disables warning on
|
||||||
|
// signed/unsigned mismatch.
|
||||||
|
#endif
|
||||||
|
|
||||||
if (expected == actual) {
|
if (expected == actual) {
|
||||||
return AssertionSuccess();
|
return AssertionSuccess();
|
||||||
}
|
}
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
#endif
|
||||||
|
|
||||||
return EqFailure(expected_expression,
|
return EqFailure(expected_expression,
|
||||||
actual_expression,
|
actual_expression,
|
||||||
@@ -784,7 +784,7 @@ class ImplicitlyConvertible {
|
|||||||
// MakeFrom() is an expression whose type is From. We cannot simply
|
// MakeFrom() is an expression whose type is From. We cannot simply
|
||||||
// use From(), as the type From may not have a public default
|
// use From(), as the type From may not have a public default
|
||||||
// constructor.
|
// constructor.
|
||||||
static typename AddReference<From>::type MakeFrom();
|
static From MakeFrom();
|
||||||
|
|
||||||
// These two functions are overloaded. Given an expression
|
// These two functions are overloaded. Given an expression
|
||||||
// Helper(x), the compiler will pick the first version if x can be
|
// Helper(x), the compiler will pick the first version if x can be
|
||||||
@@ -802,20 +802,25 @@ class ImplicitlyConvertible {
|
|||||||
// We have to put the 'public' section after the 'private' section,
|
// We have to put the 'public' section after the 'private' section,
|
||||||
// or MSVC refuses to compile the code.
|
// or MSVC refuses to compile the code.
|
||||||
public:
|
public:
|
||||||
#if defined(__BORLANDC__)
|
// MSVC warns about implicitly converting from double to int for
|
||||||
|
// possible loss of data, so we need to temporarily disable the
|
||||||
|
// warning.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4244) // Temporarily disables warning 4244.
|
||||||
|
|
||||||
|
static const bool value =
|
||||||
|
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||||
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
#elif defined(__BORLANDC__)
|
||||||
// C++Builder cannot use member overload resolution during template
|
// C++Builder cannot use member overload resolution during template
|
||||||
// instantiation. The simplest workaround is to use its C++0x type traits
|
// instantiation. The simplest workaround is to use its C++0x type traits
|
||||||
// functions (C++Builder 2009 and above only).
|
// functions (C++Builder 2009 and above only).
|
||||||
static const bool value = __is_convertible(From, To);
|
static const bool value = __is_convertible(From, To);
|
||||||
#else
|
#else
|
||||||
// MSVC warns about implicitly converting from double to int for
|
|
||||||
// possible loss of data, so we need to temporarily disable the
|
|
||||||
// warning.
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244)
|
|
||||||
static const bool value =
|
static const bool value =
|
||||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
#endif // _MSV_VER
|
||||||
#endif // __BORLANDC__
|
|
||||||
};
|
};
|
||||||
template <typename From, typename To>
|
template <typename From, typename To>
|
||||||
const bool ImplicitlyConvertible<From, To>::value;
|
const bool ImplicitlyConvertible<From, To>::value;
|
||||||
@@ -941,10 +946,11 @@ void CopyArray(const T* from, size_t size, U* to) {
|
|||||||
|
|
||||||
// The relation between an NativeArray object (see below) and the
|
// The relation between an NativeArray object (see below) and the
|
||||||
// native array it represents.
|
// native array it represents.
|
||||||
// We use 2 different structs to allow non-copyable types to be used, as long
|
enum RelationToSource {
|
||||||
// as RelationToSourceReference() is passed.
|
kReference, // The NativeArray references the native array.
|
||||||
struct RelationToSourceReference {};
|
kCopy // The NativeArray makes a copy of the native array and
|
||||||
struct RelationToSourceCopy {};
|
// owns the copy.
|
||||||
|
};
|
||||||
|
|
||||||
// Adapts a native array to a read-only STL-style container. Instead
|
// Adapts a native array to a read-only STL-style container. Instead
|
||||||
// of the complete STL container concept, this adaptor only implements
|
// of the complete STL container concept, this adaptor only implements
|
||||||
@@ -962,23 +968,22 @@ class NativeArray {
|
|||||||
typedef Element* iterator;
|
typedef Element* iterator;
|
||||||
typedef const Element* const_iterator;
|
typedef const Element* const_iterator;
|
||||||
|
|
||||||
// Constructs from a native array. References the source.
|
// Constructs from a native array.
|
||||||
NativeArray(const Element* array, size_t count, RelationToSourceReference) {
|
NativeArray(const Element* array, size_t count, RelationToSource relation) {
|
||||||
InitRef(array, count);
|
Init(array, count, relation);
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs from a native array. Copies the source.
|
|
||||||
NativeArray(const Element* array, size_t count, RelationToSourceCopy) {
|
|
||||||
InitCopy(array, count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy constructor.
|
// Copy constructor.
|
||||||
NativeArray(const NativeArray& rhs) {
|
NativeArray(const NativeArray& rhs) {
|
||||||
(this->*rhs.clone_)(rhs.array_, rhs.size_);
|
Init(rhs.array_, rhs.size_, rhs.relation_to_source_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~NativeArray() {
|
~NativeArray() {
|
||||||
if (clone_ != &NativeArray::InitRef)
|
// Ensures that the user doesn't instantiate NativeArray with a
|
||||||
|
// const or reference type.
|
||||||
|
static_cast<void>(StaticAssertTypeEqHelper<Element,
|
||||||
|
GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>());
|
||||||
|
if (relation_to_source_ == kCopy)
|
||||||
delete[] array_;
|
delete[] array_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -992,30 +997,23 @@ class NativeArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
// Initializes this object; makes a copy of the input array if
|
||||||
kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
|
// 'relation' is kCopy.
|
||||||
Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value,
|
void Init(const Element* array, size_t a_size, RelationToSource relation) {
|
||||||
};
|
if (relation == kReference) {
|
||||||
|
array_ = array;
|
||||||
// Initializes this object with a copy of the input.
|
} else {
|
||||||
void InitCopy(const Element* array, size_t a_size) {
|
Element* const copy = new Element[a_size];
|
||||||
Element* const copy = new Element[a_size];
|
CopyArray(array, a_size, copy);
|
||||||
CopyArray(array, a_size, copy);
|
array_ = copy;
|
||||||
array_ = copy;
|
}
|
||||||
size_ = a_size;
|
size_ = a_size;
|
||||||
clone_ = &NativeArray::InitCopy;
|
relation_to_source_ = relation;
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes this object with a reference of the input.
|
|
||||||
void InitRef(const Element* array, size_t a_size) {
|
|
||||||
array_ = array;
|
|
||||||
size_ = a_size;
|
|
||||||
clone_ = &NativeArray::InitRef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Element* array_;
|
const Element* array_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
void (NativeArray::*clone_)(const Element*, size_t);
|
RelationToSource relation_to_source_;
|
||||||
|
|
||||||
GTEST_DISALLOW_ASSIGN_(NativeArray);
|
GTEST_DISALLOW_ASSIGN_(NativeArray);
|
||||||
};
|
};
|
||||||
@@ -1158,4 +1156,3 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
|
|||||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
// and at most 10 arguments in Combine. Please contact
|
// and at most 10 arguments in Combine. Please contact
|
||||||
// googletestframework@googlegroups.com if you need more.
|
// googletestframework@googlegroups.com if you need more.
|
||||||
// Please note that the number of arguments to Combine is limited
|
// Please note that the number of arguments to Combine is limited
|
||||||
// by the maximum arity of the implementation of tuple which is
|
// by the maximum arity of the implementation of tr1::tuple which is
|
||||||
// currently set at 10.
|
// currently set at 10.
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||||
@@ -3157,9 +3157,9 @@ class ValueArray50 {
|
|||||||
//
|
//
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
class CartesianProductGenerator2
|
class CartesianProductGenerator2
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2> > {
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2> ParamType;
|
typedef ::std::tr1::tuple<T1, T2> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator2(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator2(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2)
|
const ParamGenerator<T2>& g2)
|
||||||
@@ -3272,9 +3272,9 @@ class CartesianProductGenerator2
|
|||||||
|
|
||||||
template <typename T1, typename T2, typename T3>
|
template <typename T1, typename T2, typename T3>
|
||||||
class CartesianProductGenerator3
|
class CartesianProductGenerator3
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3> > {
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator3(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator3(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
|
||||||
@@ -3404,9 +3404,9 @@ class CartesianProductGenerator3
|
|||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4>
|
template <typename T1, typename T2, typename T3, typename T4>
|
||||||
class CartesianProductGenerator4
|
class CartesianProductGenerator4
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4> > {
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3, T4> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator4(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator4(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
||||||
@@ -3555,9 +3555,9 @@ class CartesianProductGenerator4
|
|||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
class CartesianProductGenerator5
|
class CartesianProductGenerator5
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5> > {
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3, T4, T5> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator5(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator5(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
||||||
@@ -3723,10 +3723,10 @@ class CartesianProductGenerator5
|
|||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6>
|
typename T6>
|
||||||
class CartesianProductGenerator6
|
class CartesianProductGenerator6
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5,
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
|
||||||
T6> > {
|
T6> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3, T4, T5, T6> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator6(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator6(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
||||||
@@ -3909,10 +3909,10 @@ class CartesianProductGenerator6
|
|||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7>
|
typename T6, typename T7>
|
||||||
class CartesianProductGenerator7
|
class CartesianProductGenerator7
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
|
||||||
T7> > {
|
T7> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator7(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator7(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
||||||
@@ -4112,10 +4112,10 @@ class CartesianProductGenerator7
|
|||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7, typename T8>
|
typename T6, typename T7, typename T8>
|
||||||
class CartesianProductGenerator8
|
class CartesianProductGenerator8
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
|
||||||
T7, T8> > {
|
T7, T8> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator8(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator8(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
||||||
@@ -4334,10 +4334,10 @@ class CartesianProductGenerator8
|
|||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7, typename T8, typename T9>
|
typename T6, typename T7, typename T8, typename T9>
|
||||||
class CartesianProductGenerator9
|
class CartesianProductGenerator9
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
|
||||||
T7, T8, T9> > {
|
T7, T8, T9> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator9(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator9(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
||||||
@@ -4573,10 +4573,10 @@ class CartesianProductGenerator9
|
|||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||||
class CartesianProductGenerator10
|
class CartesianProductGenerator10
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
|
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
|
||||||
T7, T8, T9, T10> > {
|
T7, T8, T9, T10> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
|
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator10(const ParamGenerator<T1>& g1,
|
CartesianProductGenerator10(const ParamGenerator<T1>& g1,
|
||||||
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
|
||||||
@@ -4838,8 +4838,8 @@ class CartesianProductHolder2 {
|
|||||||
CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
|
CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
|
||||||
: g1_(g1), g2_(g2) {}
|
: g1_(g1), g2_(g2) {}
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2> >() const {
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2> >(
|
return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
|
||||||
new CartesianProductGenerator2<T1, T2>(
|
new CartesianProductGenerator2<T1, T2>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
static_cast<ParamGenerator<T2> >(g2_)));
|
static_cast<ParamGenerator<T2> >(g2_)));
|
||||||
@@ -4860,8 +4860,8 @@ CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
|
|||||||
const Generator3& g3)
|
const Generator3& g3)
|
||||||
: g1_(g1), g2_(g2), g3_(g3) {}
|
: g1_(g1), g2_(g2), g3_(g3) {}
|
||||||
template <typename T1, typename T2, typename T3>
|
template <typename T1, typename T2, typename T3>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3> >() const {
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3> >(
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
|
||||||
new CartesianProductGenerator3<T1, T2, T3>(
|
new CartesianProductGenerator3<T1, T2, T3>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
static_cast<ParamGenerator<T2> >(g2_),
|
static_cast<ParamGenerator<T2> >(g2_),
|
||||||
@@ -4885,8 +4885,8 @@ CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
|
|||||||
const Generator3& g3, const Generator4& g4)
|
const Generator3& g3, const Generator4& g4)
|
||||||
: g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
|
: g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
|
||||||
template <typename T1, typename T2, typename T3, typename T4>
|
template <typename T1, typename T2, typename T3, typename T4>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >() const {
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >(
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
|
||||||
new CartesianProductGenerator4<T1, T2, T3, T4>(
|
new CartesianProductGenerator4<T1, T2, T3, T4>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
static_cast<ParamGenerator<T2> >(g2_),
|
static_cast<ParamGenerator<T2> >(g2_),
|
||||||
@@ -4912,8 +4912,8 @@ CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
|
|||||||
const Generator3& g3, const Generator4& g4, const Generator5& g5)
|
const Generator3& g3, const Generator4& g4, const Generator5& g5)
|
||||||
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
|
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >() const {
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >(
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
|
||||||
new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
|
new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
static_cast<ParamGenerator<T2> >(g2_),
|
static_cast<ParamGenerator<T2> >(g2_),
|
||||||
@@ -4943,8 +4943,8 @@ CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
|
|||||||
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
|
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6>
|
typename T6>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6> >() const {
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6> >(
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
|
||||||
new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
|
new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
static_cast<ParamGenerator<T2> >(g2_),
|
static_cast<ParamGenerator<T2> >(g2_),
|
||||||
@@ -4976,9 +4976,9 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
|
|||||||
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
|
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7>
|
typename T6, typename T7>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6,
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
|
||||||
T7> >() const {
|
T7> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> >(
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
|
||||||
new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
|
new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
static_cast<ParamGenerator<T2> >(g2_),
|
static_cast<ParamGenerator<T2> >(g2_),
|
||||||
@@ -5014,9 +5014,9 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
|
|||||||
g8_(g8) {}
|
g8_(g8) {}
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7, typename T8>
|
typename T6, typename T7, typename T8>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7,
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
|
||||||
T8> >() const {
|
T8> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
|
||||||
new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
|
new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
static_cast<ParamGenerator<T2> >(g2_),
|
static_cast<ParamGenerator<T2> >(g2_),
|
||||||
@@ -5055,9 +5055,9 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
|
|||||||
g9_(g9) {}
|
g9_(g9) {}
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7, typename T8, typename T9>
|
typename T6, typename T7, typename T8, typename T9>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
|
||||||
T9> >() const {
|
T9> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
|
||||||
T9> >(
|
T9> >(
|
||||||
new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
|
new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
@@ -5099,10 +5099,10 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
|
|||||||
g9_(g9), g10_(g10) {}
|
g9_(g9), g10_(g10) {}
|
||||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||||
operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
|
||||||
T10> >() const {
|
T9, T10> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
|
||||||
T10> >(
|
T9, T10> >(
|
||||||
new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
||||||
T10>(
|
T10>(
|
||||||
static_cast<ParamGenerator<T1> >(g1_),
|
static_cast<ParamGenerator<T1> >(g1_),
|
||||||
@@ -39,7 +39,7 @@ $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
|||||||
// and at most $maxtuple arguments in Combine. Please contact
|
// and at most $maxtuple arguments in Combine. Please contact
|
||||||
// googletestframework@googlegroups.com if you need more.
|
// googletestframework@googlegroups.com if you need more.
|
||||||
// Please note that the number of arguments to Combine is limited
|
// Please note that the number of arguments to Combine is limited
|
||||||
// by the maximum arity of the implementation of tuple which is
|
// by the maximum arity of the implementation of tr1::tuple which is
|
||||||
// currently set at $maxtuple.
|
// currently set at $maxtuple.
|
||||||
|
|
||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
|
||||||
@@ -128,9 +128,9 @@ $range k 2..i
|
|||||||
|
|
||||||
template <$for j, [[typename T$j]]>
|
template <$for j, [[typename T$j]]>
|
||||||
class CartesianProductGenerator$i
|
class CartesianProductGenerator$i
|
||||||
: public ParamGeneratorInterface< ::testing::tuple<$for j, [[T$j]]> > {
|
: public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {
|
||||||
public:
|
public:
|
||||||
typedef ::testing::tuple<$for j, [[T$j]]> ParamType;
|
typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;
|
||||||
|
|
||||||
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
|
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
|
||||||
: $for j, [[g$(j)_(g$j)]] {}
|
: $for j, [[g$(j)_(g$j)]] {}
|
||||||
@@ -269,8 +269,8 @@ class CartesianProductHolder$i {
|
|||||||
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
|
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
|
||||||
: $for j, [[g$(j)_(g$j)]] {}
|
: $for j, [[g$(j)_(g$j)]] {}
|
||||||
template <$for j, [[typename T$j]]>
|
template <$for j, [[typename T$j]]>
|
||||||
operator ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >() const {
|
operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {
|
||||||
return ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >(
|
return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(
|
||||||
new CartesianProductGenerator$i<$for j, [[T$j]]>(
|
new CartesianProductGenerator$i<$for j, [[T$j]]>(
|
||||||
$for j,[[
|
$for j,[[
|
||||||
|
|
||||||
@@ -30,11 +30,8 @@
|
|||||||
// Authors: wan@google.com (Zhanyong Wan)
|
// Authors: wan@google.com (Zhanyong Wan)
|
||||||
//
|
//
|
||||||
// Low-level types and utilities for porting Google Test to various
|
// Low-level types and utilities for porting Google Test to various
|
||||||
// platforms. All macros ending with _ and symbols defined in an
|
// platforms. They are subject to change without notice. DO NOT USE
|
||||||
// internal namespace are subject to change without notice. Code
|
// THEM IN USER CODE.
|
||||||
// outside Google Test MUST NOT USE THEM DIRECTLY. Macros that don't
|
|
||||||
// end with _ are part of Google Test's public API and can be used by
|
|
||||||
// code outside Google Test.
|
|
||||||
//
|
//
|
||||||
// This file is fundamental to Google Test. All other Google Test source
|
// This file is fundamental to Google Test. All other Google Test source
|
||||||
// files are expected to #include this. Therefore, it cannot #include
|
// files are expected to #include this. Therefore, it cannot #include
|
||||||
@@ -43,30 +40,9 @@
|
|||||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||||
|
|
||||||
// Environment-describing macros
|
// The user can define the following macros in the build script to
|
||||||
// -----------------------------
|
// control Google Test's behavior. If the user doesn't define a macro
|
||||||
//
|
// in this list, Google Test will define it.
|
||||||
// Google Test can be used in many different environments. Macros in
|
|
||||||
// this section tell Google Test what kind of environment it is being
|
|
||||||
// used in, such that Google Test can provide environment-specific
|
|
||||||
// features and implementations.
|
|
||||||
//
|
|
||||||
// Google Test tries to automatically detect the properties of its
|
|
||||||
// environment, so users usually don't need to worry about these
|
|
||||||
// macros. However, the automatic detection is not perfect.
|
|
||||||
// Sometimes it's necessary for a user to define some of the following
|
|
||||||
// macros in the build script to override Google Test's decisions.
|
|
||||||
//
|
|
||||||
// If the user doesn't define a macro in the list, Google Test will
|
|
||||||
// provide a default definition. After this header is #included, all
|
|
||||||
// macros in this list will be defined to either 1 or 0.
|
|
||||||
//
|
|
||||||
// Notes to maintainers:
|
|
||||||
// - Each macro here is a user-tweakable knob; do not grow the list
|
|
||||||
// lightly.
|
|
||||||
// - Use #if to key off these macros. Don't use #ifdef or "#if
|
|
||||||
// defined(...)", which will not work as these macros are ALWAYS
|
|
||||||
// defined.
|
|
||||||
//
|
//
|
||||||
// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2)
|
// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2)
|
||||||
// is/isn't available.
|
// is/isn't available.
|
||||||
@@ -110,15 +86,10 @@
|
|||||||
// - Define to 1 when compiling Google Test itself
|
// - Define to 1 when compiling Google Test itself
|
||||||
// as a shared library.
|
// as a shared library.
|
||||||
|
|
||||||
// Platform-indicating macros
|
// This header defines the following utilities:
|
||||||
// --------------------------
|
|
||||||
//
|
|
||||||
// Macros indicating the platform on which Google Test is being used
|
|
||||||
// (a macro is defined to 1 if compiled on the given platform;
|
|
||||||
// otherwise UNDEFINED -- it's never defined to 0.). Google Test
|
|
||||||
// defines these macros automatically. Code outside Google Test MUST
|
|
||||||
// NOT define them.
|
|
||||||
//
|
//
|
||||||
|
// Macros indicating the current platform (defined to 1 if compiled on
|
||||||
|
// the given platform; otherwise undefined):
|
||||||
// GTEST_OS_AIX - IBM AIX
|
// GTEST_OS_AIX - IBM AIX
|
||||||
// GTEST_OS_CYGWIN - Cygwin
|
// GTEST_OS_CYGWIN - Cygwin
|
||||||
// GTEST_OS_HPUX - HP-UX
|
// GTEST_OS_HPUX - HP-UX
|
||||||
@@ -136,8 +107,6 @@
|
|||||||
// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
|
// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
|
||||||
// GTEST_OS_WINDOWS_MINGW - MinGW
|
// GTEST_OS_WINDOWS_MINGW - MinGW
|
||||||
// GTEST_OS_WINDOWS_MOBILE - Windows Mobile
|
// GTEST_OS_WINDOWS_MOBILE - Windows Mobile
|
||||||
// GTEST_OS_WINDOWS_PHONE - Windows Phone
|
|
||||||
// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT
|
|
||||||
// GTEST_OS_ZOS - z/OS
|
// GTEST_OS_ZOS - z/OS
|
||||||
//
|
//
|
||||||
// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
|
// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
|
||||||
@@ -147,50 +116,22 @@
|
|||||||
// googletestframework@googlegroups.com (patches for fixing them are
|
// googletestframework@googlegroups.com (patches for fixing them are
|
||||||
// even more welcome!).
|
// even more welcome!).
|
||||||
//
|
//
|
||||||
// It is possible that none of the GTEST_OS_* macros are defined.
|
// Note that it is possible that none of the GTEST_OS_* macros are defined.
|
||||||
|
|
||||||
// Feature-indicating macros
|
|
||||||
// -------------------------
|
|
||||||
//
|
|
||||||
// Macros indicating which Google Test features are available (a macro
|
|
||||||
// is defined to 1 if the corresponding feature is supported;
|
|
||||||
// otherwise UNDEFINED -- it's never defined to 0.). Google Test
|
|
||||||
// defines these macros automatically. Code outside Google Test MUST
|
|
||||||
// NOT define them.
|
|
||||||
//
|
|
||||||
// These macros are public so that portable tests can be written.
|
|
||||||
// Such tests typically surround code using a feature with an #if
|
|
||||||
// which controls that code. For example:
|
|
||||||
//
|
|
||||||
// #if GTEST_HAS_DEATH_TEST
|
|
||||||
// EXPECT_DEATH(DoSomethingDeadly());
|
|
||||||
// #endif
|
|
||||||
//
|
//
|
||||||
|
// Macros indicating available Google Test features (defined to 1 if
|
||||||
|
// the corresponding feature is supported; otherwise undefined):
|
||||||
// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized
|
// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized
|
||||||
// tests)
|
// tests)
|
||||||
// GTEST_HAS_DEATH_TEST - death tests
|
// GTEST_HAS_DEATH_TEST - death tests
|
||||||
// GTEST_HAS_PARAM_TEST - value-parameterized tests
|
// GTEST_HAS_PARAM_TEST - value-parameterized tests
|
||||||
// GTEST_HAS_TYPED_TEST - typed tests
|
// GTEST_HAS_TYPED_TEST - typed tests
|
||||||
// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
|
// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
|
||||||
// GTEST_IS_THREADSAFE - Google Test is thread-safe.
|
|
||||||
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
|
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
|
||||||
// GTEST_HAS_POSIX_RE (see above) which users can
|
// GTEST_HAS_POSIX_RE (see above) which users can
|
||||||
// define themselves.
|
// define themselves.
|
||||||
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
|
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
|
||||||
// the above two are mutually exclusive.
|
// the above two are mutually exclusive.
|
||||||
// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
|
// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
|
||||||
|
|
||||||
// Misc public macros
|
|
||||||
// ------------------
|
|
||||||
//
|
|
||||||
// GTEST_FLAG(flag_name) - references the variable corresponding to
|
|
||||||
// the given Google Test flag.
|
|
||||||
|
|
||||||
// Internal utilities
|
|
||||||
// ------------------
|
|
||||||
//
|
|
||||||
// The following macros and utilities are for Google Test's INTERNAL
|
|
||||||
// use only. Code outside Google Test MUST NOT USE THEM DIRECTLY.
|
|
||||||
//
|
//
|
||||||
// Macros for basic C++ coding:
|
// Macros for basic C++ coding:
|
||||||
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
|
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
|
||||||
@@ -199,18 +140,13 @@
|
|||||||
// GTEST_DISALLOW_ASSIGN_ - disables operator=.
|
// GTEST_DISALLOW_ASSIGN_ - disables operator=.
|
||||||
// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
|
// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
|
||||||
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
|
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
|
||||||
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
|
|
||||||
// suppressed (constant conditional).
|
|
||||||
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
|
|
||||||
// is suppressed.
|
|
||||||
//
|
|
||||||
// C++11 feature wrappers:
|
|
||||||
//
|
|
||||||
// GTEST_MOVE_ - portability wrapper for std::move.
|
|
||||||
//
|
//
|
||||||
// Synchronization:
|
// Synchronization:
|
||||||
// Mutex, MutexLock, ThreadLocal, GetThreadCount()
|
// Mutex, MutexLock, ThreadLocal, GetThreadCount()
|
||||||
// - synchronization primitives.
|
// - synchronization primitives.
|
||||||
|
// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above
|
||||||
|
// synchronization primitives have real implementations
|
||||||
|
// and Google Test is thread-safe; or 0 otherwise.
|
||||||
//
|
//
|
||||||
// Template meta programming:
|
// Template meta programming:
|
||||||
// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only.
|
// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only.
|
||||||
@@ -246,6 +182,7 @@
|
|||||||
// BiggestInt - the biggest signed integer type.
|
// BiggestInt - the biggest signed integer type.
|
||||||
//
|
//
|
||||||
// Command-line utilities:
|
// Command-line utilities:
|
||||||
|
// GTEST_FLAG() - references a flag.
|
||||||
// GTEST_DECLARE_*() - declares a flag.
|
// GTEST_DECLARE_*() - declares a flag.
|
||||||
// GTEST_DEFINE_*() - defines a flag.
|
// GTEST_DEFINE_*() - defines a flag.
|
||||||
// GetInjectableArgvs() - returns the command line as a vector of strings.
|
// GetInjectableArgvs() - returns the command line as a vector of strings.
|
||||||
@@ -271,11 +208,9 @@
|
|||||||
# include <TargetConditionals.h>
|
# include <TargetConditionals.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm> // NOLINT
|
|
||||||
#include <iostream> // NOLINT
|
#include <iostream> // NOLINT
|
||||||
#include <sstream> // NOLINT
|
#include <sstream> // NOLINT
|
||||||
#include <string> // NOLINT
|
#include <string> // NOLINT
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
|
#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
|
||||||
#define GTEST_FLAG_PREFIX_ "gtest_"
|
#define GTEST_FLAG_PREFIX_ "gtest_"
|
||||||
@@ -302,19 +237,6 @@
|
|||||||
# define GTEST_OS_WINDOWS_MOBILE 1
|
# define GTEST_OS_WINDOWS_MOBILE 1
|
||||||
# elif defined(__MINGW__) || defined(__MINGW32__)
|
# elif defined(__MINGW__) || defined(__MINGW32__)
|
||||||
# define GTEST_OS_WINDOWS_MINGW 1
|
# define GTEST_OS_WINDOWS_MINGW 1
|
||||||
# elif defined(WINAPI_FAMILY)
|
|
||||||
# include <winapifamily.h>
|
|
||||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
# define GTEST_OS_WINDOWS_DESKTOP 1
|
|
||||||
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
|
|
||||||
# define GTEST_OS_WINDOWS_PHONE 1
|
|
||||||
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
|
||||||
# define GTEST_OS_WINDOWS_RT 1
|
|
||||||
# else
|
|
||||||
// WINAPI_FAMILY defined but no known partition matched.
|
|
||||||
// Default to desktop.
|
|
||||||
# define GTEST_OS_WINDOWS_DESKTOP 1
|
|
||||||
# endif
|
|
||||||
# else
|
# else
|
||||||
# define GTEST_OS_WINDOWS_DESKTOP 1
|
# define GTEST_OS_WINDOWS_DESKTOP 1
|
||||||
# endif // _WIN32_WCE
|
# endif // _WIN32_WCE
|
||||||
@@ -347,23 +269,6 @@
|
|||||||
# define GTEST_OS_QNX 1
|
# define GTEST_OS_QNX 1
|
||||||
#endif // __CYGWIN__
|
#endif // __CYGWIN__
|
||||||
|
|
||||||
// Macros for disabling Microsoft Visual C++ warnings.
|
|
||||||
//
|
|
||||||
// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
|
|
||||||
// /* code that triggers warnings C4800 and C4385 */
|
|
||||||
// GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
||||||
#if _MSC_VER >= 1500
|
|
||||||
# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \
|
|
||||||
__pragma(warning(push)) \
|
|
||||||
__pragma(warning(disable: warnings))
|
|
||||||
# define GTEST_DISABLE_MSC_WARNINGS_POP_() \
|
|
||||||
__pragma(warning(pop))
|
|
||||||
#else
|
|
||||||
// Older versions of MSVC don't have __pragma.
|
|
||||||
# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)
|
|
||||||
# define GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GTEST_LANG_CXX11
|
#ifndef GTEST_LANG_CXX11
|
||||||
// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when
|
// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when
|
||||||
// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a
|
// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a
|
||||||
@@ -377,58 +282,19 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// C++11 specifies that <initializer_list> provides std::initializer_list. Use
|
|
||||||
// that if gtest is used in C++11 mode and libstdc++ isn't very old (binaries
|
|
||||||
// targeting OS X 10.6 can build with clang but need to use gcc4.2's
|
|
||||||
// libstdc++).
|
|
||||||
#if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325)
|
|
||||||
# define GTEST_HAS_STD_INITIALIZER_LIST_ 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// C++11 specifies that <tuple> provides std::tuple.
|
|
||||||
// Some platforms still might not have it, however.
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
# define GTEST_HAS_STD_TUPLE_ 1
|
|
||||||
# if defined(__clang__)
|
|
||||||
// Inspired by http://clang.llvm.org/docs/LanguageExtensions.html#__has_include
|
|
||||||
# if defined(__has_include) && !__has_include(<tuple>)
|
|
||||||
# undef GTEST_HAS_STD_TUPLE_
|
|
||||||
# endif
|
|
||||||
# elif defined(_MSC_VER)
|
|
||||||
// Inspired by boost/config/stdlib/dinkumware.hpp
|
|
||||||
# if defined(_CPPLIB_VER) && _CPPLIB_VER < 520
|
|
||||||
# undef GTEST_HAS_STD_TUPLE_
|
|
||||||
# endif
|
|
||||||
# elif defined(__GLIBCXX__)
|
|
||||||
// Inspired by boost/config/stdlib/libstdcpp3.hpp,
|
|
||||||
// http://gcc.gnu.org/gcc-4.2/changes.html and
|
|
||||||
// http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01.html#manual.intro.status.standard.200x
|
|
||||||
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)
|
|
||||||
# undef GTEST_HAS_STD_TUPLE_
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Brings in definitions for functions used in the testing::internal::posix
|
// Brings in definitions for functions used in the testing::internal::posix
|
||||||
// namespace (read, write, close, chdir, isatty, stat). We do not currently
|
// namespace (read, write, close, chdir, isatty, stat). We do not currently
|
||||||
// use them on Windows Mobile.
|
// use them on Windows Mobile.
|
||||||
#if GTEST_OS_WINDOWS
|
#if !GTEST_OS_WINDOWS
|
||||||
# if !GTEST_OS_WINDOWS_MOBILE
|
|
||||||
# include <direct.h>
|
|
||||||
# include <io.h>
|
|
||||||
# endif
|
|
||||||
// In order to avoid having to include <windows.h>, use forward declaration
|
|
||||||
// assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.
|
|
||||||
// This assumption is verified by
|
|
||||||
// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.
|
|
||||||
struct _RTL_CRITICAL_SECTION;
|
|
||||||
#else
|
|
||||||
// This assumes that non-Windows OSes provide unistd.h. For OSes where this
|
// This assumes that non-Windows OSes provide unistd.h. For OSes where this
|
||||||
// is not the case, we need to include headers that provide the functions
|
// is not the case, we need to include headers that provide the functions
|
||||||
// mentioned above.
|
// mentioned above.
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <strings.h>
|
# include <strings.h>
|
||||||
#endif // GTEST_OS_WINDOWS
|
#elif !GTEST_OS_WINDOWS_MOBILE
|
||||||
|
# include <direct.h>
|
||||||
|
# include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if GTEST_OS_LINUX_ANDROID
|
#if GTEST_OS_LINUX_ANDROID
|
||||||
// Used to define __ANDROID_API__ matching the target NDK API level.
|
// Used to define __ANDROID_API__ matching the target NDK API level.
|
||||||
@@ -673,21 +539,11 @@ struct _RTL_CRITICAL_SECTION;
|
|||||||
|
|
||||||
// To avoid conditional compilation everywhere, we make it
|
// To avoid conditional compilation everywhere, we make it
|
||||||
// gtest-port.h's responsibility to #include the header implementing
|
// gtest-port.h's responsibility to #include the header implementing
|
||||||
// tuple.
|
// tr1/tuple.
|
||||||
#if GTEST_HAS_STD_TUPLE_
|
|
||||||
# include <tuple> // IWYU pragma: export
|
|
||||||
# define GTEST_TUPLE_NAMESPACE_ ::std
|
|
||||||
#endif // GTEST_HAS_STD_TUPLE_
|
|
||||||
|
|
||||||
// We include tr1::tuple even if std::tuple is available to define printers for
|
|
||||||
// them.
|
|
||||||
#if GTEST_HAS_TR1_TUPLE
|
#if GTEST_HAS_TR1_TUPLE
|
||||||
# ifndef GTEST_TUPLE_NAMESPACE_
|
|
||||||
# define GTEST_TUPLE_NAMESPACE_ ::std::tr1
|
|
||||||
# endif // GTEST_TUPLE_NAMESPACE_
|
|
||||||
|
|
||||||
# if GTEST_USE_OWN_TR1_TUPLE
|
# if GTEST_USE_OWN_TR1_TUPLE
|
||||||
# include "gtest/internal/gtest-tuple.h" // IWYU pragma: export // NOLINT
|
# include "gtest/internal/gtest-tuple.h"
|
||||||
# elif GTEST_ENV_HAS_STD_TUPLE_
|
# elif GTEST_ENV_HAS_STD_TUPLE_
|
||||||
# include <tuple>
|
# include <tuple>
|
||||||
// C++11 puts its tuple into the ::std namespace rather than
|
// C++11 puts its tuple into the ::std namespace rather than
|
||||||
@@ -718,7 +574,7 @@ using ::std::tuple_size;
|
|||||||
// This prevents <boost/tr1/detail/config.hpp>, which defines
|
// This prevents <boost/tr1/detail/config.hpp>, which defines
|
||||||
// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
|
// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
|
||||||
# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
|
# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
|
||||||
# include <tuple> // IWYU pragma: export // NOLINT
|
# include <tuple>
|
||||||
|
|
||||||
# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
|
# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
|
||||||
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
|
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
|
||||||
@@ -741,7 +597,7 @@ using ::std::tuple_size;
|
|||||||
# else
|
# else
|
||||||
// If the compiler is not GCC 4.0+, we assume the user is using a
|
// If the compiler is not GCC 4.0+, we assume the user is using a
|
||||||
// spec-conforming TR1 implementation.
|
// spec-conforming TR1 implementation.
|
||||||
# include <tuple> // IWYU pragma: export // NOLINT
|
# include <tuple> // NOLINT
|
||||||
# endif // GTEST_USE_OWN_TR1_TUPLE
|
# endif // GTEST_USE_OWN_TR1_TUPLE
|
||||||
|
|
||||||
#endif // GTEST_HAS_TR1_TUPLE
|
#endif // GTEST_HAS_TR1_TUPLE
|
||||||
@@ -775,8 +631,7 @@ using ::std::tuple_size;
|
|||||||
#ifndef GTEST_HAS_STREAM_REDIRECTION
|
#ifndef GTEST_HAS_STREAM_REDIRECTION
|
||||||
// By default, we assume that stream redirection is supported on all
|
// By default, we assume that stream redirection is supported on all
|
||||||
// platforms except known mobile ones.
|
// platforms except known mobile ones.
|
||||||
# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || \
|
# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN
|
||||||
GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
|
|
||||||
# define GTEST_HAS_STREAM_REDIRECTION 0
|
# define GTEST_HAS_STREAM_REDIRECTION 0
|
||||||
# else
|
# else
|
||||||
# define GTEST_HAS_STREAM_REDIRECTION 1
|
# define GTEST_HAS_STREAM_REDIRECTION 1
|
||||||
@@ -883,25 +738,6 @@ using ::std::tuple_size;
|
|||||||
# define GTEST_MUST_USE_RESULT_
|
# define GTEST_MUST_USE_RESULT_
|
||||||
#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
|
#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
|
||||||
|
|
||||||
#if GTEST_LANG_CXX11
|
|
||||||
# define GTEST_MOVE_(x) ::std::move(x) // NOLINT
|
|
||||||
#else
|
|
||||||
# define GTEST_MOVE_(x) x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MS C++ compiler emits warning when a conditional expression is compile time
|
|
||||||
// constant. In some contexts this warning is false positive and needs to be
|
|
||||||
// suppressed. Use the following two macros in such cases:
|
|
||||||
//
|
|
||||||
// GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
|
||||||
// while (true) {
|
|
||||||
// GTEST_INTENTIONAL_CONST_COND_POP_()
|
|
||||||
// }
|
|
||||||
# define GTEST_INTENTIONAL_CONST_COND_PUSH_() \
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127)
|
|
||||||
# define GTEST_INTENTIONAL_CONST_COND_POP_() \
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
|
||||||
|
|
||||||
// Determine whether the compiler supports Microsoft's Structured Exception
|
// Determine whether the compiler supports Microsoft's Structured Exception
|
||||||
// Handling. This is supported by several Windows compilers but generally
|
// Handling. This is supported by several Windows compilers but generally
|
||||||
// does not exist on any other system.
|
// does not exist on any other system.
|
||||||
@@ -916,9 +752,6 @@ using ::std::tuple_size;
|
|||||||
# define GTEST_HAS_SEH 0
|
# define GTEST_HAS_SEH 0
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#define GTEST_IS_THREADSAFE \
|
|
||||||
(GTEST_OS_WINDOWS || GTEST_HAS_PTHREAD)
|
|
||||||
|
|
||||||
#endif // GTEST_HAS_SEH
|
#endif // GTEST_HAS_SEH
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@@ -949,58 +782,10 @@ using ::std::tuple_size;
|
|||||||
# define GTEST_HAS_CXXABI_H_ 0
|
# define GTEST_HAS_CXXABI_H_ 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// A function level attribute to disable checking for use of uninitialized
|
|
||||||
// memory when built with MemorySanitizer.
|
|
||||||
#if defined(__clang__)
|
|
||||||
# if __has_feature(memory_sanitizer)
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ \
|
|
||||||
__attribute__((no_sanitize_memory))
|
|
||||||
# else
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
||||||
# endif // __has_feature(memory_sanitizer)
|
|
||||||
#else
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
// A function level attribute to disable AddressSanitizer instrumentation.
|
|
||||||
#if defined(__clang__)
|
|
||||||
# if __has_feature(address_sanitizer)
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \
|
|
||||||
__attribute__((no_sanitize_address))
|
|
||||||
# else
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
||||||
# endif // __has_feature(address_sanitizer)
|
|
||||||
#else
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
// A function level attribute to disable ThreadSanitizer instrumentation.
|
|
||||||
#if defined(__clang__)
|
|
||||||
# if __has_feature(thread_sanitizer)
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \
|
|
||||||
__attribute__((no_sanitize_thread))
|
|
||||||
# else
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
||||||
# endif // __has_feature(thread_sanitizer)
|
|
||||||
#else
|
|
||||||
# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
class Message;
|
class Message;
|
||||||
|
|
||||||
#if defined(GTEST_TUPLE_NAMESPACE_)
|
|
||||||
// Import tuple and friends into the ::testing namespace.
|
|
||||||
// It is part of our interface, having them in ::testing allows us to change
|
|
||||||
// their types as needed.
|
|
||||||
using GTEST_TUPLE_NAMESPACE_::get;
|
|
||||||
using GTEST_TUPLE_NAMESPACE_::make_tuple;
|
|
||||||
using GTEST_TUPLE_NAMESPACE_::tuple;
|
|
||||||
using GTEST_TUPLE_NAMESPACE_::tuple_size;
|
|
||||||
using GTEST_TUPLE_NAMESPACE_::tuple_element;
|
|
||||||
#endif // defined(GTEST_TUPLE_NAMESPACE_)
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// A secret type that Google Test users don't know about. It has no
|
// A secret type that Google Test users don't know about. It has no
|
||||||
@@ -1012,8 +797,8 @@ class Secret;
|
|||||||
// expression is true. For example, you could use it to verify the
|
// expression is true. For example, you could use it to verify the
|
||||||
// size of a static array:
|
// size of a static array:
|
||||||
//
|
//
|
||||||
// GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES,
|
// GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
|
||||||
// names_incorrect_size);
|
// content_type_names_incorrect_size);
|
||||||
//
|
//
|
||||||
// or to make sure a struct is smaller than a certain size:
|
// or to make sure a struct is smaller than a certain size:
|
||||||
//
|
//
|
||||||
@@ -1079,12 +864,7 @@ template <typename T1, typename T2>
|
|||||||
struct StaticAssertTypeEqHelper;
|
struct StaticAssertTypeEqHelper;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct StaticAssertTypeEqHelper<T, T> {
|
struct StaticAssertTypeEqHelper<T, T> {};
|
||||||
enum { value = true };
|
|
||||||
};
|
|
||||||
|
|
||||||
// Evaluates to the number of elements in 'array'.
|
|
||||||
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
|
|
||||||
|
|
||||||
#if GTEST_HAS_GLOBAL_STRING
|
#if GTEST_HAS_GLOBAL_STRING
|
||||||
typedef ::string string;
|
typedef ::string string;
|
||||||
@@ -1133,11 +913,6 @@ class scoped_ptr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
friend void swap(scoped_ptr& a, scoped_ptr& b) {
|
|
||||||
using std::swap;
|
|
||||||
swap(a.ptr_, b.ptr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* ptr_;
|
T* ptr_;
|
||||||
|
|
||||||
@@ -1349,9 +1124,7 @@ inline To DownCast_(From* f) { // so we only accept pointers
|
|||||||
// for compile-time type checking, and has no overhead in an
|
// for compile-time type checking, and has no overhead in an
|
||||||
// optimized build at run-time, as it will be optimized away
|
// optimized build at run-time, as it will be optimized away
|
||||||
// completely.
|
// completely.
|
||||||
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
|
||||||
if (false) {
|
if (false) {
|
||||||
GTEST_INTENTIONAL_CONST_COND_POP_()
|
|
||||||
const To to = NULL;
|
const To to = NULL;
|
||||||
::testing::internal::ImplicitCast_<From*>(to);
|
::testing::internal::ImplicitCast_<From*>(to);
|
||||||
}
|
}
|
||||||
@@ -1406,11 +1179,12 @@ extern ::std::vector<testing::internal::string> g_argvs;
|
|||||||
#endif // GTEST_HAS_DEATH_TEST
|
#endif // GTEST_HAS_DEATH_TEST
|
||||||
|
|
||||||
// Defines synchronization primitives.
|
// Defines synchronization primitives.
|
||||||
#if GTEST_IS_THREADSAFE
|
|
||||||
# if GTEST_HAS_PTHREAD
|
#if GTEST_HAS_PTHREAD
|
||||||
// Sleeps for (roughly) n milliseconds. This function is only for testing
|
|
||||||
// Google Test's own constructs. Don't use it in user tests, either
|
// Sleeps for (roughly) n milli-seconds. This function is only for
|
||||||
// directly or indirectly.
|
// testing Google Test's own constructs. Don't use it in user tests,
|
||||||
|
// either directly or indirectly.
|
||||||
inline void SleepMilliseconds(int n) {
|
inline void SleepMilliseconds(int n) {
|
||||||
const timespec time = {
|
const timespec time = {
|
||||||
0, // 0 seconds.
|
0, // 0 seconds.
|
||||||
@@ -1418,10 +1192,7 @@ inline void SleepMilliseconds(int n) {
|
|||||||
};
|
};
|
||||||
nanosleep(&time, NULL);
|
nanosleep(&time, NULL);
|
||||||
}
|
}
|
||||||
# endif // GTEST_HAS_PTHREAD
|
|
||||||
|
|
||||||
# if 0 // OS detection
|
|
||||||
# elif GTEST_HAS_PTHREAD
|
|
||||||
// Allows a controller thread to pause execution of newly created
|
// Allows a controller thread to pause execution of newly created
|
||||||
// threads until notified. Instances of this class must be created
|
// threads until notified. Instances of this class must be created
|
||||||
// and destroyed in the controller thread.
|
// and destroyed in the controller thread.
|
||||||
@@ -1465,62 +1236,6 @@ class Notification {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
||||||
};
|
};
|
||||||
|
|
||||||
# elif GTEST_OS_WINDOWS
|
|
||||||
|
|
||||||
GTEST_API_ void SleepMilliseconds(int n);
|
|
||||||
|
|
||||||
// Provides leak-safe Windows kernel handle ownership.
|
|
||||||
// Used in death tests and in threading support.
|
|
||||||
class GTEST_API_ AutoHandle {
|
|
||||||
public:
|
|
||||||
// Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to
|
|
||||||
// avoid including <windows.h> in this header file. Including <windows.h> is
|
|
||||||
// undesirable because it defines a lot of symbols and macros that tend to
|
|
||||||
// conflict with client code. This assumption is verified by
|
|
||||||
// WindowsTypesTest.HANDLEIsVoidStar.
|
|
||||||
typedef void* Handle;
|
|
||||||
AutoHandle();
|
|
||||||
explicit AutoHandle(Handle handle);
|
|
||||||
|
|
||||||
~AutoHandle();
|
|
||||||
|
|
||||||
Handle Get() const;
|
|
||||||
void Reset();
|
|
||||||
void Reset(Handle handle);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Returns true iff the handle is a valid handle object that can be closed.
|
|
||||||
bool IsCloseable() const;
|
|
||||||
|
|
||||||
Handle handle_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allows a controller thread to pause execution of newly created
|
|
||||||
// threads until notified. Instances of this class must be created
|
|
||||||
// and destroyed in the controller thread.
|
|
||||||
//
|
|
||||||
// This class is only for testing Google Test's own constructs. Do not
|
|
||||||
// use it in user tests, either directly or indirectly.
|
|
||||||
class GTEST_API_ Notification {
|
|
||||||
public:
|
|
||||||
Notification();
|
|
||||||
void Notify();
|
|
||||||
void WaitForNotification();
|
|
||||||
|
|
||||||
private:
|
|
||||||
AutoHandle event_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
|
|
||||||
};
|
|
||||||
# endif // OS detection
|
|
||||||
|
|
||||||
// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD
|
|
||||||
// defined, but we don't want to use MinGW's pthreads implementation, which
|
|
||||||
// has conformance problems with some versions of the POSIX standard.
|
|
||||||
# if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW
|
|
||||||
|
|
||||||
// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
|
// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
|
||||||
// Consequently, it cannot select a correct instantiation of ThreadWithParam
|
// Consequently, it cannot select a correct instantiation of ThreadWithParam
|
||||||
// in order to call its Run(). Introducing ThreadWithParamBase as a
|
// in order to call its Run(). Introducing ThreadWithParamBase as a
|
||||||
@@ -1558,9 +1273,10 @@ extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadWithParam : public ThreadWithParamBase {
|
class ThreadWithParam : public ThreadWithParamBase {
|
||||||
public:
|
public:
|
||||||
typedef void UserThreadFunc(T);
|
typedef void (*UserThreadFunc)(T);
|
||||||
|
|
||||||
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
|
ThreadWithParam(
|
||||||
|
UserThreadFunc func, T param, Notification* thread_can_start)
|
||||||
: func_(func),
|
: func_(func),
|
||||||
param_(param),
|
param_(param),
|
||||||
thread_can_start_(thread_can_start),
|
thread_can_start_(thread_can_start),
|
||||||
@@ -1587,7 +1303,7 @@ class ThreadWithParam : public ThreadWithParamBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UserThreadFunc* const func_; // User-supplied thread function.
|
const UserThreadFunc func_; // User-supplied thread function.
|
||||||
const T param_; // User-supplied parameter to the thread function.
|
const T param_; // User-supplied parameter to the thread function.
|
||||||
// When non-NULL, used to block execution until the controller thread
|
// When non-NULL, used to block execution until the controller thread
|
||||||
// notifies.
|
// notifies.
|
||||||
@@ -1597,255 +1313,26 @@ class ThreadWithParam : public ThreadWithParamBase {
|
|||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
|
||||||
};
|
};
|
||||||
# endif // GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW
|
|
||||||
|
|
||||||
# if 0 // OS detection
|
// MutexBase and Mutex implement mutex on pthreads-based platforms. They
|
||||||
# elif GTEST_OS_WINDOWS
|
// are used in conjunction with class MutexLock:
|
||||||
|
|
||||||
// Mutex implements mutex on Windows platforms. It is used in conjunction
|
|
||||||
// with class MutexLock:
|
|
||||||
//
|
//
|
||||||
// Mutex mutex;
|
// Mutex mutex;
|
||||||
// ...
|
// ...
|
||||||
// MutexLock lock(&mutex); // Acquires the mutex and releases it at the
|
// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end
|
||||||
// // end of the current scope.
|
// // of the current scope.
|
||||||
|
//
|
||||||
|
// MutexBase implements behavior for both statically and dynamically
|
||||||
|
// allocated mutexes. Do not use MutexBase directly. Instead, write
|
||||||
|
// the following to define a static mutex:
|
||||||
//
|
//
|
||||||
// A static Mutex *must* be defined or declared using one of the following
|
|
||||||
// macros:
|
|
||||||
// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
|
// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
|
||||||
|
//
|
||||||
|
// You can forward declare a static mutex like this:
|
||||||
|
//
|
||||||
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
|
// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
|
||||||
//
|
//
|
||||||
// (A non-static Mutex is defined/declared in the usual way).
|
// To create a dynamic mutex, just define an object of type Mutex.
|
||||||
class GTEST_API_ Mutex {
|
|
||||||
public:
|
|
||||||
enum MutexType { kStatic = 0, kDynamic = 1 };
|
|
||||||
// We rely on kStaticMutex being 0 as it is to what the linker initializes
|
|
||||||
// type_ in static mutexes. critical_section_ will be initialized lazily
|
|
||||||
// in ThreadSafeLazyInit().
|
|
||||||
enum StaticConstructorSelector { kStaticMutex = 0 };
|
|
||||||
|
|
||||||
// This constructor intentionally does nothing. It relies on type_ being
|
|
||||||
// statically initialized to 0 (effectively setting it to kStatic) and on
|
|
||||||
// ThreadSafeLazyInit() to lazily initialize the rest of the members.
|
|
||||||
explicit Mutex(StaticConstructorSelector /*dummy*/) {}
|
|
||||||
|
|
||||||
Mutex();
|
|
||||||
~Mutex();
|
|
||||||
|
|
||||||
void Lock();
|
|
||||||
|
|
||||||
void Unlock();
|
|
||||||
|
|
||||||
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
|
||||||
// with high probability.
|
|
||||||
void AssertHeld();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Initializes owner_thread_id_ and critical_section_ in static mutexes.
|
|
||||||
void ThreadSafeLazyInit();
|
|
||||||
|
|
||||||
// Per http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx,
|
|
||||||
// we assume that 0 is an invalid value for thread IDs.
|
|
||||||
unsigned int owner_thread_id_;
|
|
||||||
|
|
||||||
// For static mutexes, we rely on these members being initialized to zeros
|
|
||||||
// by the linker.
|
|
||||||
MutexType type_;
|
|
||||||
long critical_section_init_phase_; // NOLINT
|
|
||||||
_RTL_CRITICAL_SECTION* critical_section_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
|
|
||||||
};
|
|
||||||
|
|
||||||
# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
|
||||||
extern ::testing::internal::Mutex mutex
|
|
||||||
|
|
||||||
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
|
||||||
::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex)
|
|
||||||
|
|
||||||
// We cannot name this class MutexLock because the ctor declaration would
|
|
||||||
// conflict with a macro named MutexLock, which is defined on some
|
|
||||||
// platforms. That macro is used as a defensive measure to prevent against
|
|
||||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
|
||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
|
||||||
class GTestMutexLock {
|
|
||||||
public:
|
|
||||||
explicit GTestMutexLock(Mutex* mutex)
|
|
||||||
: mutex_(mutex) { mutex_->Lock(); }
|
|
||||||
|
|
||||||
~GTestMutexLock() { mutex_->Unlock(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Mutex* const mutex_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef GTestMutexLock MutexLock;
|
|
||||||
|
|
||||||
// Base class for ValueHolder<T>. Allows a caller to hold and delete a value
|
|
||||||
// without knowing its type.
|
|
||||||
class ThreadLocalValueHolderBase {
|
|
||||||
public:
|
|
||||||
virtual ~ThreadLocalValueHolderBase() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Provides a way for a thread to send notifications to a ThreadLocal
|
|
||||||
// regardless of its parameter type.
|
|
||||||
class ThreadLocalBase {
|
|
||||||
public:
|
|
||||||
// Creates a new ValueHolder<T> object holding a default value passed to
|
|
||||||
// this ThreadLocal<T>'s constructor and returns it. It is the caller's
|
|
||||||
// responsibility not to call this when the ThreadLocal<T> instance already
|
|
||||||
// has a value on the current thread.
|
|
||||||
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ThreadLocalBase() {}
|
|
||||||
virtual ~ThreadLocalBase() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Maps a thread to a set of ThreadLocals that have values instantiated on that
|
|
||||||
// thread and notifies them when the thread exits. A ThreadLocal instance is
|
|
||||||
// expected to persist until all threads it has values on have terminated.
|
|
||||||
class GTEST_API_ ThreadLocalRegistry {
|
|
||||||
public:
|
|
||||||
// Registers thread_local_instance as having value on the current thread.
|
|
||||||
// Returns a value that can be used to identify the thread from other threads.
|
|
||||||
static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
|
|
||||||
const ThreadLocalBase* thread_local_instance);
|
|
||||||
|
|
||||||
// Invoked when a ThreadLocal instance is destroyed.
|
|
||||||
static void OnThreadLocalDestroyed(
|
|
||||||
const ThreadLocalBase* thread_local_instance);
|
|
||||||
};
|
|
||||||
|
|
||||||
class GTEST_API_ ThreadWithParamBase {
|
|
||||||
public:
|
|
||||||
void Join();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class Runnable {
|
|
||||||
public:
|
|
||||||
virtual ~Runnable() {}
|
|
||||||
virtual void Run() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start);
|
|
||||||
virtual ~ThreadWithParamBase();
|
|
||||||
|
|
||||||
private:
|
|
||||||
AutoHandle thread_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper class for testing Google Test's multi-threading constructs.
|
|
||||||
template <typename T>
|
|
||||||
class ThreadWithParam : public ThreadWithParamBase {
|
|
||||||
public:
|
|
||||||
typedef void UserThreadFunc(T);
|
|
||||||
|
|
||||||
ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start)
|
|
||||||
: ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {
|
|
||||||
}
|
|
||||||
virtual ~ThreadWithParam() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class RunnableImpl : public Runnable {
|
|
||||||
public:
|
|
||||||
RunnableImpl(UserThreadFunc* func, T param)
|
|
||||||
: func_(func),
|
|
||||||
param_(param) {
|
|
||||||
}
|
|
||||||
virtual ~RunnableImpl() {}
|
|
||||||
virtual void Run() {
|
|
||||||
func_(param_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
UserThreadFunc* const func_;
|
|
||||||
const T param_;
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl);
|
|
||||||
};
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements thread-local storage on Windows systems.
|
|
||||||
//
|
|
||||||
// // Thread 1
|
|
||||||
// ThreadLocal<int> tl(100); // 100 is the default value for each thread.
|
|
||||||
//
|
|
||||||
// // Thread 2
|
|
||||||
// tl.set(150); // Changes the value for thread 2 only.
|
|
||||||
// EXPECT_EQ(150, tl.get());
|
|
||||||
//
|
|
||||||
// // Thread 1
|
|
||||||
// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value.
|
|
||||||
// tl.set(200);
|
|
||||||
// EXPECT_EQ(200, tl.get());
|
|
||||||
//
|
|
||||||
// The template type argument T must have a public copy constructor.
|
|
||||||
// In addition, the default ThreadLocal constructor requires T to have
|
|
||||||
// a public default constructor.
|
|
||||||
//
|
|
||||||
// The users of a TheadLocal instance have to make sure that all but one
|
|
||||||
// threads (including the main one) using that instance have exited before
|
|
||||||
// destroying it. Otherwise, the per-thread objects managed for them by the
|
|
||||||
// ThreadLocal instance are not guaranteed to be destroyed on all platforms.
|
|
||||||
//
|
|
||||||
// Google Test only uses global ThreadLocal objects. That means they
|
|
||||||
// will die after main() has returned. Therefore, no per-thread
|
|
||||||
// object managed by Google Test will be leaked as long as all threads
|
|
||||||
// using Google Test have exited when main() returns.
|
|
||||||
template <typename T>
|
|
||||||
class ThreadLocal : public ThreadLocalBase {
|
|
||||||
public:
|
|
||||||
ThreadLocal() : default_() {}
|
|
||||||
explicit ThreadLocal(const T& value) : default_(value) {}
|
|
||||||
|
|
||||||
~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }
|
|
||||||
|
|
||||||
T* pointer() { return GetOrCreateValue(); }
|
|
||||||
const T* pointer() const { return GetOrCreateValue(); }
|
|
||||||
const T& get() const { return *pointer(); }
|
|
||||||
void set(const T& value) { *pointer() = value; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Holds a value of T. Can be deleted via its base class without the caller
|
|
||||||
// knowing the type of T.
|
|
||||||
class ValueHolder : public ThreadLocalValueHolderBase {
|
|
||||||
public:
|
|
||||||
explicit ValueHolder(const T& value) : value_(value) {}
|
|
||||||
|
|
||||||
T* pointer() { return &value_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
T value_;
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
T* GetOrCreateValue() const {
|
|
||||||
return static_cast<ValueHolder*>(
|
|
||||||
ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const {
|
|
||||||
return new ValueHolder(default_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const T default_; // The default value for each thread.
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
|
||||||
};
|
|
||||||
|
|
||||||
# elif GTEST_HAS_PTHREAD
|
|
||||||
|
|
||||||
// MutexBase and Mutex implement mutex on pthreads-based platforms.
|
|
||||||
class MutexBase {
|
class MutexBase {
|
||||||
public:
|
public:
|
||||||
// Acquires this mutex.
|
// Acquires this mutex.
|
||||||
@@ -1890,8 +1377,8 @@ class MutexBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Forward-declares a static mutex.
|
// Forward-declares a static mutex.
|
||||||
# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
||||||
extern ::testing::internal::MutexBase mutex
|
extern ::testing::internal::MutexBase mutex
|
||||||
|
|
||||||
// Defines and statically (i.e. at link time) initializes a static mutex.
|
// Defines and statically (i.e. at link time) initializes a static mutex.
|
||||||
// The initialization list here does not explicitly initialize each field,
|
// The initialization list here does not explicitly initialize each field,
|
||||||
@@ -1899,8 +1386,8 @@ class MutexBase {
|
|||||||
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
|
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
|
||||||
// This allows initialization to work whether pthread_t is a scalar or struct.
|
// This allows initialization to work whether pthread_t is a scalar or struct.
|
||||||
// The flag -Wmissing-field-initializers must not be specified for this to work.
|
// The flag -Wmissing-field-initializers must not be specified for this to work.
|
||||||
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
||||||
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }
|
::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }
|
||||||
|
|
||||||
// The Mutex class can only be used for mutexes created at runtime. It
|
// The Mutex class can only be used for mutexes created at runtime. It
|
||||||
// shares its API with MutexBase otherwise.
|
// shares its API with MutexBase otherwise.
|
||||||
@@ -1918,11 +1405,9 @@ class Mutex : public MutexBase {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
|
||||||
};
|
};
|
||||||
|
|
||||||
// We cannot name this class MutexLock because the ctor declaration would
|
// We cannot name this class MutexLock as the ctor declaration would
|
||||||
// conflict with a macro named MutexLock, which is defined on some
|
// conflict with a macro named MutexLock, which is defined on some
|
||||||
// platforms. That macro is used as a defensive measure to prevent against
|
// platforms. Hence the typedef trick below.
|
||||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
|
||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
|
||||||
class GTestMutexLock {
|
class GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(MutexBase* mutex)
|
explicit GTestMutexLock(MutexBase* mutex)
|
||||||
@@ -1956,6 +1441,34 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implements thread-local storage on pthreads-based systems.
|
// Implements thread-local storage on pthreads-based systems.
|
||||||
|
//
|
||||||
|
// // Thread 1
|
||||||
|
// ThreadLocal<int> tl(100); // 100 is the default value for each thread.
|
||||||
|
//
|
||||||
|
// // Thread 2
|
||||||
|
// tl.set(150); // Changes the value for thread 2 only.
|
||||||
|
// EXPECT_EQ(150, tl.get());
|
||||||
|
//
|
||||||
|
// // Thread 1
|
||||||
|
// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value.
|
||||||
|
// tl.set(200);
|
||||||
|
// EXPECT_EQ(200, tl.get());
|
||||||
|
//
|
||||||
|
// The template type argument T must have a public copy constructor.
|
||||||
|
// In addition, the default ThreadLocal constructor requires T to have
|
||||||
|
// a public default constructor.
|
||||||
|
//
|
||||||
|
// An object managed for a thread by a ThreadLocal instance is deleted
|
||||||
|
// when the thread exits. Or, if the ThreadLocal instance dies in
|
||||||
|
// that thread, when the ThreadLocal dies. It's the user's
|
||||||
|
// responsibility to ensure that all other threads using a ThreadLocal
|
||||||
|
// have exited when it dies, or the per-thread objects for those
|
||||||
|
// threads will not be deleted.
|
||||||
|
//
|
||||||
|
// Google Test only uses global ThreadLocal objects. That means they
|
||||||
|
// will die after main() has returned. Therefore, no per-thread
|
||||||
|
// object managed by Google Test will be leaked as long as all threads
|
||||||
|
// using Google Test have exited when main() returns.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ThreadLocal {
|
class ThreadLocal {
|
||||||
public:
|
public:
|
||||||
@@ -2020,9 +1533,9 @@ class ThreadLocal {
|
|||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
||||||
};
|
};
|
||||||
|
|
||||||
# endif // OS detection
|
# define GTEST_IS_THREADSAFE 1
|
||||||
|
|
||||||
#else // GTEST_IS_THREADSAFE
|
#else // GTEST_HAS_PTHREAD
|
||||||
|
|
||||||
// A dummy implementation of synchronization primitives (mutex, lock,
|
// A dummy implementation of synchronization primitives (mutex, lock,
|
||||||
// and thread-local variable). Necessary for compiling Google Test where
|
// and thread-local variable). Necessary for compiling Google Test where
|
||||||
@@ -2042,11 +1555,6 @@ class Mutex {
|
|||||||
|
|
||||||
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
|
# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
|
||||||
|
|
||||||
// We cannot name this class MutexLock because the ctor declaration would
|
|
||||||
// conflict with a macro named MutexLock, which is defined on some
|
|
||||||
// platforms. That macro is used as a defensive measure to prevent against
|
|
||||||
// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than
|
|
||||||
// "MutexLock l(&mu)". Hence the typedef trick below.
|
|
||||||
class GTestMutexLock {
|
class GTestMutexLock {
|
||||||
public:
|
public:
|
||||||
explicit GTestMutexLock(Mutex*) {} // NOLINT
|
explicit GTestMutexLock(Mutex*) {} // NOLINT
|
||||||
@@ -2067,7 +1575,11 @@ class ThreadLocal {
|
|||||||
T value_;
|
T value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTEST_IS_THREADSAFE
|
// The above synchronization primitives have dummy implementations.
|
||||||
|
// Therefore Google Test is not thread-safe.
|
||||||
|
# define GTEST_IS_THREADSAFE 0
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_PTHREAD
|
||||||
|
|
||||||
// Returns the number of threads running in the process, or 0 to indicate that
|
// Returns the number of threads running in the process, or 0 to indicate that
|
||||||
// we cannot detect it.
|
// we cannot detect it.
|
||||||
@@ -2240,7 +1752,11 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
|||||||
|
|
||||||
// Functions deprecated by MSVC 8.0.
|
// Functions deprecated by MSVC 8.0.
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */)
|
#ifdef _MSC_VER
|
||||||
|
// Temporarily disable warning 4996 (deprecated function).
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4996)
|
||||||
|
#endif
|
||||||
|
|
||||||
inline const char* StrNCpy(char* dest, const char* src, size_t n) {
|
inline const char* StrNCpy(char* dest, const char* src, size_t n) {
|
||||||
return strncpy(dest, src, n);
|
return strncpy(dest, src, n);
|
||||||
@@ -2250,7 +1766,7 @@ inline const char* StrNCpy(char* dest, const char* src, size_t n) {
|
|||||||
// StrError() aren't needed on Windows CE at this time and thus not
|
// StrError() aren't needed on Windows CE at this time and thus not
|
||||||
// defined there.
|
// defined there.
|
||||||
|
|
||||||
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
#if !GTEST_OS_WINDOWS_MOBILE
|
||||||
inline int ChDir(const char* dir) { return chdir(dir); }
|
inline int ChDir(const char* dir) { return chdir(dir); }
|
||||||
#endif
|
#endif
|
||||||
inline FILE* FOpen(const char* path, const char* mode) {
|
inline FILE* FOpen(const char* path, const char* mode) {
|
||||||
@@ -2274,7 +1790,7 @@ inline int Close(int fd) { return close(fd); }
|
|||||||
inline const char* StrError(int errnum) { return strerror(errnum); }
|
inline const char* StrError(int errnum) { return strerror(errnum); }
|
||||||
#endif
|
#endif
|
||||||
inline const char* GetEnv(const char* name) {
|
inline const char* GetEnv(const char* name) {
|
||||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE | GTEST_OS_WINDOWS_RT
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
// We are on Windows CE, which has no environment variables.
|
// We are on Windows CE, which has no environment variables.
|
||||||
return NULL;
|
return NULL;
|
||||||
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
|
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
|
||||||
@@ -2287,7 +1803,9 @@ inline const char* GetEnv(const char* name) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
#endif
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
// Windows CE has no C library. The abort() function is used in
|
// Windows CE has no C library. The abort() function is used in
|
||||||
@@ -2427,4 +1945,3 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
|
|||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
|
||||||
|
|
||||||
@@ -53,14 +53,6 @@
|
|||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
|
|
||||||
// with our own definitions. Therefore using our own tuple does not work on
|
|
||||||
// those compilers.
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */
|
|
||||||
# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
|
|
||||||
GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
|
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
|
||||||
#define GTEST_0_TUPLE_(T) tuple<>
|
#define GTEST_0_TUPLE_(T) tuple<>
|
||||||
#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
|
#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
|
||||||
@@ -52,14 +52,6 @@ $$ This meta comment fixes auto-indentation in Emacs. }}
|
|||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
|
|
||||||
// with our own definitions. Therefore using our own tuple does not work on
|
|
||||||
// those compilers.
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */
|
|
||||||
# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
|
|
||||||
GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
$range i 0..n-1
|
$range i 0..n-1
|
||||||
$range j 0..n
|
$range j 0..n
|
||||||
@@ -70,6 +70,7 @@ namespace internal {
|
|||||||
// of them.
|
// of them.
|
||||||
const char kPathSeparator = '\\';
|
const char kPathSeparator = '\\';
|
||||||
const char kAlternatePathSeparator = '/';
|
const char kAlternatePathSeparator = '/';
|
||||||
|
const char kPathSeparatorString[] = "\\";
|
||||||
const char kAlternatePathSeparatorString[] = "/";
|
const char kAlternatePathSeparatorString[] = "/";
|
||||||
# if GTEST_OS_WINDOWS_MOBILE
|
# if GTEST_OS_WINDOWS_MOBILE
|
||||||
// Windows CE doesn't have a current directory. You should not use
|
// Windows CE doesn't have a current directory. You should not use
|
||||||
@@ -83,6 +84,7 @@ const char kCurrentDirectoryString[] = ".\\";
|
|||||||
# endif // GTEST_OS_WINDOWS_MOBILE
|
# endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
#else
|
#else
|
||||||
const char kPathSeparator = '/';
|
const char kPathSeparator = '/';
|
||||||
|
const char kPathSeparatorString[] = "/";
|
||||||
const char kCurrentDirectoryString[] = "./";
|
const char kCurrentDirectoryString[] = "./";
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ static bool IsPathSeparator(char c) {
|
|||||||
|
|
||||||
// Returns the current working directory, or "" if unsuccessful.
|
// Returns the current working directory, or "" if unsuccessful.
|
||||||
FilePath FilePath::GetCurrentDir() {
|
FilePath FilePath::GetCurrentDir() {
|
||||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
// Windows CE doesn't have a current directory, so we just return
|
// Windows CE doesn't have a current directory, so we just return
|
||||||
// something reasonable.
|
// something reasonable.
|
||||||
return FilePath(kCurrentDirectoryString);
|
return FilePath(kCurrentDirectoryString);
|
||||||
@@ -968,6 +968,32 @@ GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
|
|||||||
// platform.
|
// platform.
|
||||||
GTEST_API_ std::string GetLastErrnoDescription();
|
GTEST_API_ std::string GetLastErrnoDescription();
|
||||||
|
|
||||||
|
# if GTEST_OS_WINDOWS
|
||||||
|
// Provides leak-safe Windows kernel handle ownership.
|
||||||
|
class AutoHandle {
|
||||||
|
public:
|
||||||
|
AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
|
||||||
|
explicit AutoHandle(HANDLE handle) : handle_(handle) {}
|
||||||
|
|
||||||
|
~AutoHandle() { Reset(); }
|
||||||
|
|
||||||
|
HANDLE Get() const { return handle_; }
|
||||||
|
void Reset() { Reset(INVALID_HANDLE_VALUE); }
|
||||||
|
void Reset(HANDLE handle) {
|
||||||
|
if (handle != handle_) {
|
||||||
|
if (handle_ != INVALID_HANDLE_VALUE)
|
||||||
|
::CloseHandle(handle_);
|
||||||
|
handle_ = handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE handle_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
|
||||||
|
};
|
||||||
|
# endif // GTEST_OS_WINDOWS
|
||||||
|
|
||||||
// Attempts to parse a string into a positive integer pointed to by the
|
// Attempts to parse a string into a positive integer pointed to by the
|
||||||
// number parameter. Returns true if that is possible.
|
// number parameter. Returns true if that is possible.
|
||||||
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
|
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
|
||||||
@@ -36,14 +36,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
# include <windows.h>
|
# include <windows.h> // For TerminateProcess()
|
||||||
|
#elif GTEST_OS_WINDOWS
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
# include <map> // Used in ThreadLocal.
|
|
||||||
#else
|
#else
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif // GTEST_OS_WINDOWS
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
|
||||||
#if GTEST_OS_MAC
|
#if GTEST_OS_MAC
|
||||||
# include <mach/mach_init.h>
|
# include <mach/mach_init.h>
|
||||||
@@ -53,7 +53,6 @@
|
|||||||
|
|
||||||
#if GTEST_OS_QNX
|
#if GTEST_OS_QNX
|
||||||
# include <devctl.h>
|
# include <devctl.h>
|
||||||
# include <fcntl.h>
|
|
||||||
# include <sys/procfs.h>
|
# include <sys/procfs.h>
|
||||||
#endif // GTEST_OS_QNX
|
#endif // GTEST_OS_QNX
|
||||||
|
|
||||||
@@ -134,389 +133,6 @@ size_t GetThreadCount() {
|
|||||||
|
|
||||||
#endif // GTEST_OS_MAC
|
#endif // GTEST_OS_MAC
|
||||||
|
|
||||||
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
|
||||||
|
|
||||||
void SleepMilliseconds(int n) {
|
|
||||||
::Sleep(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoHandle::AutoHandle()
|
|
||||||
: handle_(INVALID_HANDLE_VALUE) {}
|
|
||||||
|
|
||||||
AutoHandle::AutoHandle(Handle handle)
|
|
||||||
: handle_(handle) {}
|
|
||||||
|
|
||||||
AutoHandle::~AutoHandle() {
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoHandle::Handle AutoHandle::Get() const {
|
|
||||||
return handle_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AutoHandle::Reset() {
|
|
||||||
Reset(INVALID_HANDLE_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AutoHandle::Reset(HANDLE handle) {
|
|
||||||
// Resetting with the same handle we already own is invalid.
|
|
||||||
if (handle_ != handle) {
|
|
||||||
if (IsCloseable()) {
|
|
||||||
::CloseHandle(handle_);
|
|
||||||
}
|
|
||||||
handle_ = handle;
|
|
||||||
} else {
|
|
||||||
GTEST_CHECK_(!IsCloseable())
|
|
||||||
<< "Resetting a valid handle to itself is likely a programmer error "
|
|
||||||
"and thus not allowed.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AutoHandle::IsCloseable() const {
|
|
||||||
// Different Windows APIs may use either of these values to represent an
|
|
||||||
// invalid handle.
|
|
||||||
return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Notification::Notification()
|
|
||||||
: event_(::CreateEvent(NULL, // Default security attributes.
|
|
||||||
TRUE, // Do not reset automatically.
|
|
||||||
FALSE, // Initially unset.
|
|
||||||
NULL)) { // Anonymous event.
|
|
||||||
GTEST_CHECK_(event_.Get() != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notification::Notify() {
|
|
||||||
GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notification::WaitForNotification() {
|
|
||||||
GTEST_CHECK_(
|
|
||||||
::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutex::Mutex()
|
|
||||||
: type_(kDynamic),
|
|
||||||
owner_thread_id_(0),
|
|
||||||
critical_section_init_phase_(0),
|
|
||||||
critical_section_(new CRITICAL_SECTION) {
|
|
||||||
::InitializeCriticalSection(critical_section_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutex::~Mutex() {
|
|
||||||
// Static mutexes are leaked intentionally. It is not thread-safe to try
|
|
||||||
// to clean them up.
|
|
||||||
// TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires
|
|
||||||
// nothing to clean it up but is available only on Vista and later.
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx
|
|
||||||
if (type_ == kDynamic) {
|
|
||||||
::DeleteCriticalSection(critical_section_);
|
|
||||||
delete critical_section_;
|
|
||||||
critical_section_ = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex::Lock() {
|
|
||||||
ThreadSafeLazyInit();
|
|
||||||
::EnterCriticalSection(critical_section_);
|
|
||||||
owner_thread_id_ = ::GetCurrentThreadId();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex::Unlock() {
|
|
||||||
ThreadSafeLazyInit();
|
|
||||||
// We don't protect writing to owner_thread_id_ here, as it's the
|
|
||||||
// caller's responsibility to ensure that the current thread holds the
|
|
||||||
// mutex when this is called.
|
|
||||||
owner_thread_id_ = 0;
|
|
||||||
::LeaveCriticalSection(critical_section_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does nothing if the current thread holds the mutex. Otherwise, crashes
|
|
||||||
// with high probability.
|
|
||||||
void Mutex::AssertHeld() {
|
|
||||||
ThreadSafeLazyInit();
|
|
||||||
GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())
|
|
||||||
<< "The current thread is not holding the mutex @" << this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes owner_thread_id_ and critical_section_ in static mutexes.
|
|
||||||
void Mutex::ThreadSafeLazyInit() {
|
|
||||||
// Dynamic mutexes are initialized in the constructor.
|
|
||||||
if (type_ == kStatic) {
|
|
||||||
switch (
|
|
||||||
::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {
|
|
||||||
case 0:
|
|
||||||
// If critical_section_init_phase_ was 0 before the exchange, we
|
|
||||||
// are the first to test it and need to perform the initialization.
|
|
||||||
owner_thread_id_ = 0;
|
|
||||||
critical_section_ = new CRITICAL_SECTION;
|
|
||||||
::InitializeCriticalSection(critical_section_);
|
|
||||||
// Updates the critical_section_init_phase_ to 2 to signal
|
|
||||||
// initialization complete.
|
|
||||||
GTEST_CHECK_(::InterlockedCompareExchange(
|
|
||||||
&critical_section_init_phase_, 2L, 1L) ==
|
|
||||||
1L);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// Somebody else is already initializing the mutex; spin until they
|
|
||||||
// are done.
|
|
||||||
while (::InterlockedCompareExchange(&critical_section_init_phase_,
|
|
||||||
2L,
|
|
||||||
2L) != 2L) {
|
|
||||||
// Possibly yields the rest of the thread's time slice to other
|
|
||||||
// threads.
|
|
||||||
::Sleep(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
break; // The mutex is already initialized and ready for use.
|
|
||||||
|
|
||||||
default:
|
|
||||||
GTEST_CHECK_(false)
|
|
||||||
<< "Unexpected value of critical_section_init_phase_ "
|
|
||||||
<< "while initializing a static mutex.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class ThreadWithParamSupport : public ThreadWithParamBase {
|
|
||||||
public:
|
|
||||||
static HANDLE CreateThread(Runnable* runnable,
|
|
||||||
Notification* thread_can_start) {
|
|
||||||
ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
|
|
||||||
DWORD thread_id;
|
|
||||||
// TODO(yukawa): Consider to use _beginthreadex instead.
|
|
||||||
HANDLE thread_handle = ::CreateThread(
|
|
||||||
NULL, // Default security.
|
|
||||||
0, // Default stack size.
|
|
||||||
&ThreadWithParamSupport::ThreadMain,
|
|
||||||
param, // Parameter to ThreadMainStatic
|
|
||||||
0x0, // Default creation flags.
|
|
||||||
&thread_id); // Need a valid pointer for the call to work under Win98.
|
|
||||||
GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error "
|
|
||||||
<< ::GetLastError() << ".";
|
|
||||||
if (thread_handle == NULL) {
|
|
||||||
delete param;
|
|
||||||
}
|
|
||||||
return thread_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct ThreadMainParam {
|
|
||||||
ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
|
|
||||||
: runnable_(runnable),
|
|
||||||
thread_can_start_(thread_can_start) {
|
|
||||||
}
|
|
||||||
scoped_ptr<Runnable> runnable_;
|
|
||||||
// Does not own.
|
|
||||||
Notification* thread_can_start_;
|
|
||||||
};
|
|
||||||
|
|
||||||
static DWORD WINAPI ThreadMain(void* ptr) {
|
|
||||||
// Transfers ownership.
|
|
||||||
scoped_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
|
|
||||||
if (param->thread_can_start_ != NULL)
|
|
||||||
param->thread_can_start_->WaitForNotification();
|
|
||||||
param->runnable_->Run();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prohibit instantiation.
|
|
||||||
ThreadWithParamSupport();
|
|
||||||
|
|
||||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable,
|
|
||||||
Notification* thread_can_start)
|
|
||||||
: thread_(ThreadWithParamSupport::CreateThread(runnable,
|
|
||||||
thread_can_start)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadWithParamBase::~ThreadWithParamBase() {
|
|
||||||
Join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadWithParamBase::Join() {
|
|
||||||
GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0)
|
|
||||||
<< "Failed to join the thread with error " << ::GetLastError() << ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maps a thread to a set of ThreadIdToThreadLocals that have values
|
|
||||||
// instantiated on that thread and notifies them when the thread exits. A
|
|
||||||
// ThreadLocal instance is expected to persist until all threads it has
|
|
||||||
// values on have terminated.
|
|
||||||
class ThreadLocalRegistryImpl {
|
|
||||||
public:
|
|
||||||
// Registers thread_local_instance as having value on the current thread.
|
|
||||||
// Returns a value that can be used to identify the thread from other threads.
|
|
||||||
static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
|
|
||||||
const ThreadLocalBase* thread_local_instance) {
|
|
||||||
DWORD current_thread = ::GetCurrentThreadId();
|
|
||||||
MutexLock lock(&mutex_);
|
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
|
||||||
GetThreadLocalsMapLocked();
|
|
||||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
|
||||||
thread_to_thread_locals->find(current_thread);
|
|
||||||
if (thread_local_pos == thread_to_thread_locals->end()) {
|
|
||||||
thread_local_pos = thread_to_thread_locals->insert(
|
|
||||||
std::make_pair(current_thread, ThreadLocalValues())).first;
|
|
||||||
StartWatcherThreadFor(current_thread);
|
|
||||||
}
|
|
||||||
ThreadLocalValues& thread_local_values = thread_local_pos->second;
|
|
||||||
ThreadLocalValues::iterator value_pos =
|
|
||||||
thread_local_values.find(thread_local_instance);
|
|
||||||
if (value_pos == thread_local_values.end()) {
|
|
||||||
value_pos =
|
|
||||||
thread_local_values
|
|
||||||
.insert(std::make_pair(
|
|
||||||
thread_local_instance,
|
|
||||||
linked_ptr<ThreadLocalValueHolderBase>(
|
|
||||||
thread_local_instance->NewValueForCurrentThread())))
|
|
||||||
.first;
|
|
||||||
}
|
|
||||||
return value_pos->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnThreadLocalDestroyed(
|
|
||||||
const ThreadLocalBase* thread_local_instance) {
|
|
||||||
std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
|
|
||||||
// Clean up the ThreadLocalValues data structure while holding the lock, but
|
|
||||||
// defer the destruction of the ThreadLocalValueHolderBases.
|
|
||||||
{
|
|
||||||
MutexLock lock(&mutex_);
|
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
|
||||||
GetThreadLocalsMapLocked();
|
|
||||||
for (ThreadIdToThreadLocals::iterator it =
|
|
||||||
thread_to_thread_locals->begin();
|
|
||||||
it != thread_to_thread_locals->end();
|
|
||||||
++it) {
|
|
||||||
ThreadLocalValues& thread_local_values = it->second;
|
|
||||||
ThreadLocalValues::iterator value_pos =
|
|
||||||
thread_local_values.find(thread_local_instance);
|
|
||||||
if (value_pos != thread_local_values.end()) {
|
|
||||||
value_holders.push_back(value_pos->second);
|
|
||||||
thread_local_values.erase(value_pos);
|
|
||||||
// This 'if' can only be successful at most once, so theoretically we
|
|
||||||
// could break out of the loop here, but we don't bother doing so.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Outside the lock, let the destructor for 'value_holders' deallocate the
|
|
||||||
// ThreadLocalValueHolderBases.
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnThreadExit(DWORD thread_id) {
|
|
||||||
GTEST_CHECK_(thread_id != 0) << ::GetLastError();
|
|
||||||
std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
|
|
||||||
// Clean up the ThreadIdToThreadLocals data structure while holding the
|
|
||||||
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
|
|
||||||
{
|
|
||||||
MutexLock lock(&mutex_);
|
|
||||||
ThreadIdToThreadLocals* const thread_to_thread_locals =
|
|
||||||
GetThreadLocalsMapLocked();
|
|
||||||
ThreadIdToThreadLocals::iterator thread_local_pos =
|
|
||||||
thread_to_thread_locals->find(thread_id);
|
|
||||||
if (thread_local_pos != thread_to_thread_locals->end()) {
|
|
||||||
ThreadLocalValues& thread_local_values = thread_local_pos->second;
|
|
||||||
for (ThreadLocalValues::iterator value_pos =
|
|
||||||
thread_local_values.begin();
|
|
||||||
value_pos != thread_local_values.end();
|
|
||||||
++value_pos) {
|
|
||||||
value_holders.push_back(value_pos->second);
|
|
||||||
}
|
|
||||||
thread_to_thread_locals->erase(thread_local_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Outside the lock, let the destructor for 'value_holders' deallocate the
|
|
||||||
// ThreadLocalValueHolderBases.
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// In a particular thread, maps a ThreadLocal object to its value.
|
|
||||||
typedef std::map<const ThreadLocalBase*,
|
|
||||||
linked_ptr<ThreadLocalValueHolderBase> > ThreadLocalValues;
|
|
||||||
// Stores all ThreadIdToThreadLocals having values in a thread, indexed by
|
|
||||||
// thread's ID.
|
|
||||||
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
|
|
||||||
|
|
||||||
// Holds the thread id and thread handle that we pass from
|
|
||||||
// StartWatcherThreadFor to WatcherThreadFunc.
|
|
||||||
typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
|
|
||||||
|
|
||||||
static void StartWatcherThreadFor(DWORD thread_id) {
|
|
||||||
// The returned handle will be kept in thread_map and closed by
|
|
||||||
// watcher_thread in WatcherThreadFunc.
|
|
||||||
HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
|
|
||||||
FALSE,
|
|
||||||
thread_id);
|
|
||||||
GTEST_CHECK_(thread != NULL);
|
|
||||||
// We need to to pass a valid thread ID pointer into CreateThread for it
|
|
||||||
// to work correctly under Win98.
|
|
||||||
DWORD watcher_thread_id;
|
|
||||||
HANDLE watcher_thread = ::CreateThread(
|
|
||||||
NULL, // Default security.
|
|
||||||
0, // Default stack size
|
|
||||||
&ThreadLocalRegistryImpl::WatcherThreadFunc,
|
|
||||||
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
|
|
||||||
CREATE_SUSPENDED,
|
|
||||||
&watcher_thread_id);
|
|
||||||
GTEST_CHECK_(watcher_thread != NULL);
|
|
||||||
// Give the watcher thread the same priority as ours to avoid being
|
|
||||||
// blocked by it.
|
|
||||||
::SetThreadPriority(watcher_thread,
|
|
||||||
::GetThreadPriority(::GetCurrentThread()));
|
|
||||||
::ResumeThread(watcher_thread);
|
|
||||||
::CloseHandle(watcher_thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Monitors exit from a given thread and notifies those
|
|
||||||
// ThreadIdToThreadLocals about thread termination.
|
|
||||||
static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
|
|
||||||
const ThreadIdAndHandle* tah =
|
|
||||||
reinterpret_cast<const ThreadIdAndHandle*>(param);
|
|
||||||
GTEST_CHECK_(
|
|
||||||
::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
|
|
||||||
OnThreadExit(tah->first);
|
|
||||||
::CloseHandle(tah->second);
|
|
||||||
delete tah;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns map of thread local instances.
|
|
||||||
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
|
|
||||||
mutex_.AssertHeld();
|
|
||||||
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protects access to GetThreadLocalsMapLocked() and its return value.
|
|
||||||
static Mutex mutex_;
|
|
||||||
// Protects access to GetThreadMapLocked() and its return value.
|
|
||||||
static Mutex thread_map_mutex_;
|
|
||||||
};
|
|
||||||
|
|
||||||
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex);
|
|
||||||
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex);
|
|
||||||
|
|
||||||
ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
|
|
||||||
const ThreadLocalBase* thread_local_instance) {
|
|
||||||
return ThreadLocalRegistryImpl::GetValueOnCurrentThread(
|
|
||||||
thread_local_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalRegistry::OnThreadLocalDestroyed(
|
|
||||||
const ThreadLocalBase* thread_local_instance) {
|
|
||||||
ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
|
||||||
|
|
||||||
#if GTEST_USES_POSIX_RE
|
#if GTEST_USES_POSIX_RE
|
||||||
|
|
||||||
// Implements RE. Currently only needed for death tests.
|
// Implements RE. Currently only needed for death tests.
|
||||||
@@ -886,7 +502,10 @@ GTestLog::~GTestLog() {
|
|||||||
}
|
}
|
||||||
// Disable Microsoft deprecation warnings for POSIX functions called from
|
// Disable Microsoft deprecation warnings for POSIX functions called from
|
||||||
// this class (creat, dup, dup2, and close)
|
// this class (creat, dup, dup2, and close)
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable: 4996)
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#if GTEST_HAS_STREAM_REDIRECTION
|
#if GTEST_HAS_STREAM_REDIRECTION
|
||||||
|
|
||||||
@@ -1005,7 +624,9 @@ std::string CapturedStream::ReadEntireFile(FILE* file) {
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
# ifdef _MSC_VER
|
||||||
|
# pragma warning(pop)
|
||||||
|
# endif // _MSC_VER
|
||||||
|
|
||||||
static CapturedStream* g_captured_stderr = NULL;
|
static CapturedStream* g_captured_stderr = NULL;
|
||||||
static CapturedStream* g_captured_stdout = NULL;
|
static CapturedStream* g_captured_stdout = NULL;
|
||||||
@@ -45,7 +45,6 @@
|
|||||||
#include "gtest/gtest-printers.h"
|
#include "gtest/gtest-printers.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <cwchar>
|
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "gtest/internal/gtest-port.h"
|
#include "gtest/internal/gtest-port.h"
|
||||||
@@ -57,9 +56,6 @@ namespace {
|
|||||||
using ::std::ostream;
|
using ::std::ostream;
|
||||||
|
|
||||||
// Prints a segment of bytes in the given object.
|
// Prints a segment of bytes in the given object.
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
||||||
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
|
||||||
size_t count, ostream* os) {
|
size_t count, ostream* os) {
|
||||||
char text[5] = "";
|
char text[5] = "";
|
||||||
@@ -256,9 +252,6 @@ void PrintTo(wchar_t wc, ostream* os) {
|
|||||||
// The array starts at begin, the length is len, it may include '\0' characters
|
// The array starts at begin, the length is len, it may include '\0' characters
|
||||||
// and may not be NUL-terminated.
|
// and may not be NUL-terminated.
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
||||||
static void PrintCharsAsStringTo(
|
static void PrintCharsAsStringTo(
|
||||||
const CharType* begin, size_t len, ostream* os) {
|
const CharType* begin, size_t len, ostream* os) {
|
||||||
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
|
||||||
@@ -280,9 +273,6 @@ static void PrintCharsAsStringTo(
|
|||||||
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
||||||
// 'begin'. CharType must be either char or wchar_t.
|
// 'begin'. CharType must be either char or wchar_t.
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
|
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
|
|
||||||
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
|
|
||||||
static void UniversalPrintCharArray(
|
static void UniversalPrintCharArray(
|
||||||
const CharType* begin, size_t len, ostream* os) {
|
const CharType* begin, size_t len, ostream* os) {
|
||||||
// The code
|
// The code
|
||||||
@@ -339,7 +329,7 @@ void PrintTo(const wchar_t* s, ostream* os) {
|
|||||||
*os << "NULL";
|
*os << "NULL";
|
||||||
} else {
|
} else {
|
||||||
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
*os << ImplicitCast_<const void*>(s) << " pointing to ";
|
||||||
PrintCharsAsStringTo(s, std::wcslen(s), os);
|
PrintCharsAsStringTo(s, wcslen(s), os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // wchar_t is native
|
#endif // wchar_t is native
|
||||||
@@ -50,8 +50,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
|
||||||
|
|
||||||
#if GTEST_OS_LINUX
|
#if GTEST_OS_LINUX
|
||||||
|
|
||||||
// TODO(kenton@google.com): Use autoconf to detect availability of
|
// TODO(kenton@google.com): Use autoconf to detect availability of
|
||||||
@@ -804,13 +802,21 @@ TimeInMillis GetTimeInMillis() {
|
|||||||
#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
|
#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
|
||||||
__timeb64 now;
|
__timeb64 now;
|
||||||
|
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
|
||||||
// MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
|
// MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
|
||||||
// (deprecated function) there.
|
// (deprecated function) there.
|
||||||
// TODO(kenton@google.com): Use GetTickCount()? Or use
|
// TODO(kenton@google.com): Use GetTickCount()? Or use
|
||||||
// SystemTimeToFileTime()
|
// SystemTimeToFileTime()
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||||
_ftime64(&now);
|
_ftime64(&now);
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
# else
|
||||||
|
|
||||||
|
_ftime64(&now);
|
||||||
|
|
||||||
|
# endif // _MSC_VER
|
||||||
|
|
||||||
return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
|
return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
|
||||||
#elif GTEST_HAS_GETTIMEOFDAY_
|
#elif GTEST_HAS_GETTIMEOFDAY_
|
||||||
@@ -950,13 +956,6 @@ AssertionResult::AssertionResult(const AssertionResult& other)
|
|||||||
static_cast< ::std::string*>(NULL)) {
|
static_cast< ::std::string*>(NULL)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swaps two AssertionResults.
|
|
||||||
void AssertionResult::swap(AssertionResult& other) {
|
|
||||||
using std::swap;
|
|
||||||
swap(success_, other.success_);
|
|
||||||
swap(message_, other.message_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
|
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
|
||||||
AssertionResult AssertionResult::operator!() const {
|
AssertionResult AssertionResult::operator!() const {
|
||||||
AssertionResult negation(!success_);
|
AssertionResult negation(!success_);
|
||||||
@@ -2555,8 +2554,7 @@ enum GTestColor {
|
|||||||
COLOR_YELLOW
|
COLOR_YELLOW
|
||||||
};
|
};
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \
|
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
|
||||||
!GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
|
||||||
|
|
||||||
// Returns the character attribute for the given color.
|
// Returns the character attribute for the given color.
|
||||||
WORD GetColorAttribute(GTestColor color) {
|
WORD GetColorAttribute(GTestColor color) {
|
||||||
@@ -2624,8 +2622,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \
|
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS
|
||||||
GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
|
|
||||||
const bool use_color = false;
|
const bool use_color = false;
|
||||||
#else
|
#else
|
||||||
static const bool in_color_mode =
|
static const bool in_color_mode =
|
||||||
@@ -2640,8 +2637,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \
|
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
|
||||||
!GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
|
||||||
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
// Gets the current text color.
|
// Gets the current text color.
|
||||||
@@ -3223,23 +3219,27 @@ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
|
|||||||
// Converts the given epoch time in milliseconds to a date string in the ISO
|
// Converts the given epoch time in milliseconds to a date string in the ISO
|
||||||
// 8601 format, without the timezone information.
|
// 8601 format, without the timezone information.
|
||||||
std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
|
std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {
|
||||||
|
// Using non-reentrant version as localtime_r is not portable.
|
||||||
time_t seconds = static_cast<time_t>(ms / 1000);
|
time_t seconds = static_cast<time_t>(ms / 1000);
|
||||||
struct tm time_struct;
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
if (localtime_s(&time_struct, &seconds) != 0)
|
# pragma warning(push) // Saves the current warning state.
|
||||||
return ""; // Invalid ms value
|
# pragma warning(disable:4996) // Temporarily disables warning 4996
|
||||||
|
// (function or variable may be unsafe).
|
||||||
|
const struct tm* const time_struct = localtime(&seconds); // NOLINT
|
||||||
|
# pragma warning(pop) // Restores the warning state again.
|
||||||
#else
|
#else
|
||||||
if (localtime_r(&seconds, &time_struct) == NULL)
|
const struct tm* const time_struct = localtime(&seconds); // NOLINT
|
||||||
return ""; // Invalid ms value
|
|
||||||
#endif
|
#endif
|
||||||
|
if (time_struct == NULL)
|
||||||
|
return ""; // Invalid ms value
|
||||||
|
|
||||||
// YYYY-MM-DDThh:mm:ss
|
// YYYY-MM-DDThh:mm:ss
|
||||||
return StreamableToString(time_struct.tm_year + 1900) + "-" +
|
return StreamableToString(time_struct->tm_year + 1900) + "-" +
|
||||||
String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" +
|
String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" +
|
||||||
String::FormatIntWidth2(time_struct.tm_mday) + "T" +
|
String::FormatIntWidth2(time_struct->tm_mday) + "T" +
|
||||||
String::FormatIntWidth2(time_struct.tm_hour) + ":" +
|
String::FormatIntWidth2(time_struct->tm_hour) + ":" +
|
||||||
String::FormatIntWidth2(time_struct.tm_min) + ":" +
|
String::FormatIntWidth2(time_struct->tm_min) + ":" +
|
||||||
String::FormatIntWidth2(time_struct.tm_sec);
|
String::FormatIntWidth2(time_struct->tm_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
|
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
|
||||||
@@ -3812,7 +3812,7 @@ void UnitTest::AddTestPartResult(
|
|||||||
// with another testing framework) and specify the former on the
|
// with another testing framework) and specify the former on the
|
||||||
// command line for debugging.
|
// command line for debugging.
|
||||||
if (GTEST_FLAG(break_on_failure)) {
|
if (GTEST_FLAG(break_on_failure)) {
|
||||||
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
#if GTEST_OS_WINDOWS
|
||||||
// Using DebugBreak on Windows allows gtest to still break into a debugger
|
// Using DebugBreak on Windows allows gtest to still break into a debugger
|
||||||
// when a failure happens and both the --gtest_break_on_failure and
|
// when a failure happens and both the --gtest_break_on_failure and
|
||||||
// the --gtest_catch_exceptions flags are specified.
|
// the --gtest_catch_exceptions flags are specified.
|
||||||
@@ -3890,7 +3890,7 @@ int UnitTest::Run() {
|
|||||||
// process. In either case the user does not want to see pop-up dialogs
|
// process. In either case the user does not want to see pop-up dialogs
|
||||||
// about crashes - they are expected.
|
// about crashes - they are expected.
|
||||||
if (impl()->catch_exceptions() || in_death_test_child_process) {
|
if (impl()->catch_exceptions() || in_death_test_child_process) {
|
||||||
# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
|
# if !GTEST_OS_WINDOWS_MOBILE
|
||||||
// SetErrorMode doesn't exist on CE.
|
// SetErrorMode doesn't exist on CE.
|
||||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
|
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
|
||||||
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
||||||
@@ -3993,10 +3993,17 @@ namespace internal {
|
|||||||
|
|
||||||
UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
UnitTestImpl::UnitTestImpl(UnitTest* parent)
|
||||||
: parent_(parent),
|
: parent_(parent),
|
||||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4355) // Temporarily disables warning 4355
|
||||||
|
// (using this in initializer).
|
||||||
default_global_test_part_result_reporter_(this),
|
default_global_test_part_result_reporter_(this),
|
||||||
default_per_thread_test_part_result_reporter_(this),
|
default_per_thread_test_part_result_reporter_(this),
|
||||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
# pragma warning(pop) // Restores the warning state again.
|
||||||
|
#else
|
||||||
|
default_global_test_part_result_reporter_(this),
|
||||||
|
default_per_thread_test_part_result_reporter_(this),
|
||||||
|
#endif // _MSC_VER
|
||||||
global_test_part_result_repoter_(
|
global_test_part_result_repoter_(
|
||||||
&default_global_test_part_result_reporter_),
|
&default_global_test_part_result_reporter_),
|
||||||
per_thread_test_part_result_reporter_(
|
per_thread_test_part_result_reporter_(
|
||||||
1078
gmock/include/gmock/gmock-actions.h
Normal file
1078
gmock/include/gmock/gmock-actions.h
Normal file
File diff suppressed because it is too large
Load Diff
147
gmock/include/gmock/gmock-cardinalities.h
Normal file
147
gmock/include/gmock/gmock-cardinalities.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements some commonly used cardinalities. More
|
||||||
|
// cardinalities can be defined by the user implementing the
|
||||||
|
// CardinalityInterface interface if necessary.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <ostream> // NOLINT
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// To implement a cardinality Foo, define:
|
||||||
|
// 1. a class FooCardinality that implements the
|
||||||
|
// CardinalityInterface interface, and
|
||||||
|
// 2. a factory function that creates a Cardinality object from a
|
||||||
|
// const FooCardinality*.
|
||||||
|
//
|
||||||
|
// The two-level delegation design follows that of Matcher, providing
|
||||||
|
// consistency for extension developers. It also eases ownership
|
||||||
|
// management as Cardinality objects can now be copied like plain values.
|
||||||
|
|
||||||
|
// The implementation of a cardinality.
|
||||||
|
class CardinalityInterface {
|
||||||
|
public:
|
||||||
|
virtual ~CardinalityInterface() {}
|
||||||
|
|
||||||
|
// Conservative estimate on the lower/upper bound of the number of
|
||||||
|
// calls allowed.
|
||||||
|
virtual int ConservativeLowerBound() const { return 0; }
|
||||||
|
virtual int ConservativeUpperBound() const { return INT_MAX; }
|
||||||
|
|
||||||
|
// Returns true iff call_count calls will satisfy this cardinality.
|
||||||
|
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
|
||||||
|
|
||||||
|
// Returns true iff call_count calls will saturate this cardinality.
|
||||||
|
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
|
||||||
|
|
||||||
|
// Describes self to an ostream.
|
||||||
|
virtual void DescribeTo(::std::ostream* os) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
|
||||||
|
// object that specifies how many times a mock function is expected to
|
||||||
|
// be called. The implementation of Cardinality is just a linked_ptr
|
||||||
|
// to const CardinalityInterface, so copying is fairly cheap.
|
||||||
|
// Don't inherit from Cardinality!
|
||||||
|
class GTEST_API_ Cardinality {
|
||||||
|
public:
|
||||||
|
// Constructs a null cardinality. Needed for storing Cardinality
|
||||||
|
// objects in STL containers.
|
||||||
|
Cardinality() {}
|
||||||
|
|
||||||
|
// Constructs a Cardinality from its implementation.
|
||||||
|
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {}
|
||||||
|
|
||||||
|
// Conservative estimate on the lower/upper bound of the number of
|
||||||
|
// calls allowed.
|
||||||
|
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
|
||||||
|
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
|
||||||
|
|
||||||
|
// Returns true iff call_count calls will satisfy this cardinality.
|
||||||
|
bool IsSatisfiedByCallCount(int call_count) const {
|
||||||
|
return impl_->IsSatisfiedByCallCount(call_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true iff call_count calls will saturate this cardinality.
|
||||||
|
bool IsSaturatedByCallCount(int call_count) const {
|
||||||
|
return impl_->IsSaturatedByCallCount(call_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true iff call_count calls will over-saturate this
|
||||||
|
// cardinality, i.e. exceed the maximum number of allowed calls.
|
||||||
|
bool IsOverSaturatedByCallCount(int call_count) const {
|
||||||
|
return impl_->IsSaturatedByCallCount(call_count) &&
|
||||||
|
!impl_->IsSatisfiedByCallCount(call_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describes self to an ostream
|
||||||
|
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
|
||||||
|
|
||||||
|
// Describes the given actual call count to an ostream.
|
||||||
|
static void DescribeActualCallCountTo(int actual_call_count,
|
||||||
|
::std::ostream* os);
|
||||||
|
|
||||||
|
private:
|
||||||
|
internal::linked_ptr<const CardinalityInterface> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates a cardinality that allows at least n calls.
|
||||||
|
GTEST_API_ Cardinality AtLeast(int n);
|
||||||
|
|
||||||
|
// Creates a cardinality that allows at most n calls.
|
||||||
|
GTEST_API_ Cardinality AtMost(int n);
|
||||||
|
|
||||||
|
// Creates a cardinality that allows any number of calls.
|
||||||
|
GTEST_API_ Cardinality AnyNumber();
|
||||||
|
|
||||||
|
// Creates a cardinality that allows between min and max calls.
|
||||||
|
GTEST_API_ Cardinality Between(int min, int max);
|
||||||
|
|
||||||
|
// Creates a cardinality that allows exactly n calls.
|
||||||
|
GTEST_API_ Cardinality Exactly(int n);
|
||||||
|
|
||||||
|
// Creates a cardinality from its implementation.
|
||||||
|
inline Cardinality MakeCardinality(const CardinalityInterface* c) {
|
||||||
|
return Cardinality(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
|
||||||
2415
gmock/include/gmock/gmock-generated-actions.h
Normal file
2415
gmock/include/gmock/gmock-generated-actions.h
Normal file
File diff suppressed because it is too large
Load Diff
821
gmock/include/gmock/gmock-generated-actions.h.pump
Normal file
821
gmock/include/gmock/gmock-generated-actions.h.pump
Normal file
@@ -0,0 +1,821 @@
|
|||||||
|
$$ -*- mode: c++; -*-
|
||||||
|
$$ This is a Pump source file. Please use Pump to convert it to
|
||||||
|
$$ gmock-generated-actions.h.
|
||||||
|
$$
|
||||||
|
$var n = 10 $$ The maximum arity we support.
|
||||||
|
$$}} This meta comment fixes auto-indentation in editors.
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements some commonly used variadic actions.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||||
|
|
||||||
|
#include "gmock/gmock-actions.h"
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
|
||||||
|
// function or method with the unpacked values, where F is a function
|
||||||
|
// type that takes N arguments.
|
||||||
|
template <typename Result, typename ArgumentTuple>
|
||||||
|
class InvokeHelper;
|
||||||
|
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
$var types = [[$for j [[, typename A$j]]]]
|
||||||
|
$var as = [[$for j, [[A$j]]]]
|
||||||
|
$var args = [[$if i==0 [[]] $else [[ args]]]]
|
||||||
|
$var import = [[$if i==0 [[]] $else [[
|
||||||
|
using ::std::tr1::get;
|
||||||
|
|
||||||
|
]]]]
|
||||||
|
$var gets = [[$for j, [[get<$(j - 1)>(args)]]]]
|
||||||
|
template <typename R$types>
|
||||||
|
class InvokeHelper<R, ::std::tr1::tuple<$as> > {
|
||||||
|
public:
|
||||||
|
template <typename Function>
|
||||||
|
static R Invoke(Function function, const ::std::tr1::tuple<$as>&$args) {
|
||||||
|
$import return function($gets);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Class, typename MethodPtr>
|
||||||
|
static R InvokeMethod(Class* obj_ptr,
|
||||||
|
MethodPtr method_ptr,
|
||||||
|
const ::std::tr1::tuple<$as>&$args) {
|
||||||
|
$import return (obj_ptr->*method_ptr)($gets);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
// CallableHelper has static methods for invoking "callables",
|
||||||
|
// i.e. function pointers and functors. It uses overloading to
|
||||||
|
// provide a uniform interface for invoking different kinds of
|
||||||
|
// callables. In particular, you can use:
|
||||||
|
//
|
||||||
|
// CallableHelper<R>::Call(callable, a1, a2, ..., an)
|
||||||
|
//
|
||||||
|
// to invoke an n-ary callable, where R is its return type. If an
|
||||||
|
// argument, say a2, needs to be passed by reference, you should write
|
||||||
|
// ByRef(a2) instead of a2 in the above expression.
|
||||||
|
template <typename R>
|
||||||
|
class CallableHelper {
|
||||||
|
public:
|
||||||
|
// Calls a nullary callable.
|
||||||
|
template <typename Function>
|
||||||
|
static R Call(Function function) { return function(); }
|
||||||
|
|
||||||
|
// Calls a unary callable.
|
||||||
|
|
||||||
|
// We deliberately pass a1 by value instead of const reference here
|
||||||
|
// in case it is a C-string literal. If we had declared the
|
||||||
|
// parameter as 'const A1& a1' and write Call(function, "Hi"), the
|
||||||
|
// compiler would've thought A1 is 'char[3]', which causes trouble
|
||||||
|
// when you need to copy a value of type A1. By declaring the
|
||||||
|
// parameter as 'A1 a1', the compiler will correctly infer that A1
|
||||||
|
// is 'const char*' when it sees Call(function, "Hi").
|
||||||
|
//
|
||||||
|
// Since this function is defined inline, the compiler can get rid
|
||||||
|
// of the copying of the arguments. Therefore the performance won't
|
||||||
|
// be hurt.
|
||||||
|
template <typename Function, typename A1>
|
||||||
|
static R Call(Function function, A1 a1) { return function(a1); }
|
||||||
|
|
||||||
|
$range i 2..n
|
||||||
|
$for i
|
||||||
|
[[
|
||||||
|
$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
|
||||||
|
|
||||||
|
// Calls a $arity callable.
|
||||||
|
|
||||||
|
$range j 1..i
|
||||||
|
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||||
|
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||||
|
$var as = [[$for j, [[a$j]]]]
|
||||||
|
$var typename_Ts = [[$for j, [[typename T$j]]]]
|
||||||
|
$var Ts = [[$for j, [[T$j]]]]
|
||||||
|
template <typename Function, $typename_As>
|
||||||
|
static R Call(Function function, $Aas) {
|
||||||
|
return function($as);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
}; // class CallableHelper
|
||||||
|
|
||||||
|
// An INTERNAL macro for extracting the type of a tuple field. It's
|
||||||
|
// subject to change without notice - DO NOT USE IN USER CODE!
|
||||||
|
#define GMOCK_FIELD_(Tuple, N) \
|
||||||
|
typename ::std::tr1::tuple_element<N, Tuple>::type
|
||||||
|
|
||||||
|
$range i 1..n
|
||||||
|
|
||||||
|
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
|
||||||
|
// type of an n-ary function whose i-th (1-based) argument type is the
|
||||||
|
// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
|
||||||
|
// type, and whose return type is Result. For example,
|
||||||
|
// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type
|
||||||
|
// is int(bool, long).
|
||||||
|
//
|
||||||
|
// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
|
||||||
|
// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
|
||||||
|
// For example,
|
||||||
|
// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select(
|
||||||
|
// ::std::tr1::make_tuple(true, 'a', 2.5))
|
||||||
|
// returns ::std::tr1::tuple (2.5, true).
|
||||||
|
//
|
||||||
|
// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
|
||||||
|
// in the range [0, $n]. Duplicates are allowed and they don't have
|
||||||
|
// to be in an ascending or descending order.
|
||||||
|
|
||||||
|
template <typename Result, typename ArgumentTuple, $for i, [[int k$i]]>
|
||||||
|
class SelectArgs {
|
||||||
|
public:
|
||||||
|
typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]);
|
||||||
|
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||||
|
static SelectedArgs Select(const ArgumentTuple& args) {
|
||||||
|
using ::std::tr1::get;
|
||||||
|
return SelectedArgs($for i, [[get<k$i>(args)]]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 1..n
|
||||||
|
$range j1 1..i-1
|
||||||
|
template <typename Result, typename ArgumentTuple$for j1[[, int k$j1]]>
|
||||||
|
class SelectArgs<Result, ArgumentTuple,
|
||||||
|
$for j, [[$if j <= i-1 [[k$j]] $else [[-1]]]]> {
|
||||||
|
public:
|
||||||
|
typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]);
|
||||||
|
typedef typename Function<type>::ArgumentTuple SelectedArgs;
|
||||||
|
static SelectedArgs Select(const ArgumentTuple& [[]]
|
||||||
|
$if i == 1 [[/* args */]] $else [[args]]) {
|
||||||
|
using ::std::tr1::get;
|
||||||
|
return SelectedArgs($for j1, [[get<k$j1>(args)]]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
#undef GMOCK_FIELD_
|
||||||
|
|
||||||
|
$var ks = [[$for i, [[k$i]]]]
|
||||||
|
|
||||||
|
// Implements the WithArgs action.
|
||||||
|
template <typename InnerAction, $for i, [[int k$i = -1]]>
|
||||||
|
class WithArgsAction {
|
||||||
|
public:
|
||||||
|
explicit WithArgsAction(const InnerAction& action) : action_(action) {}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename F>
|
||||||
|
class Impl : public ActionInterface<F> {
|
||||||
|
public:
|
||||||
|
typedef typename Function<F>::Result Result;
|
||||||
|
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
explicit Impl(const InnerAction& action) : action_(action) {}
|
||||||
|
|
||||||
|
virtual Result Perform(const ArgumentTuple& args) {
|
||||||
|
return action_.Perform(SelectArgs<Result, ArgumentTuple, $ks>::Select(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef typename SelectArgs<Result, ArgumentTuple,
|
||||||
|
$ks>::type InnerFunctionType;
|
||||||
|
|
||||||
|
Action<InnerFunctionType> action_;
|
||||||
|
};
|
||||||
|
|
||||||
|
const InnerAction action_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(WithArgsAction);
|
||||||
|
};
|
||||||
|
|
||||||
|
// A macro from the ACTION* family (defined later in this file)
|
||||||
|
// defines an action that can be used in a mock function. Typically,
|
||||||
|
// these actions only care about a subset of the arguments of the mock
|
||||||
|
// function. For example, if such an action only uses the second
|
||||||
|
// argument, it can be used in any mock function that takes >= 2
|
||||||
|
// arguments where the type of the second argument is compatible.
|
||||||
|
//
|
||||||
|
// Therefore, the action implementation must be prepared to take more
|
||||||
|
// arguments than it needs. The ExcessiveArg type is used to
|
||||||
|
// represent those excessive arguments. In order to keep the compiler
|
||||||
|
// error messages tractable, we define it in the testing namespace
|
||||||
|
// instead of testing::internal. However, this is an INTERNAL TYPE
|
||||||
|
// and subject to change without notice, so a user MUST NOT USE THIS
|
||||||
|
// TYPE DIRECTLY.
|
||||||
|
struct ExcessiveArg {};
|
||||||
|
|
||||||
|
// A helper class needed for implementing the ACTION* macros.
|
||||||
|
template <typename Result, class Impl>
|
||||||
|
class ActionHelper {
|
||||||
|
public:
|
||||||
|
$range i 0..n
|
||||||
|
$for i
|
||||||
|
|
||||||
|
[[
|
||||||
|
$var template = [[$if i==0 [[]] $else [[
|
||||||
|
$range j 0..i-1
|
||||||
|
template <$for j, [[typename A$j]]>
|
||||||
|
]]]]
|
||||||
|
$range j 0..i-1
|
||||||
|
$var As = [[$for j, [[A$j]]]]
|
||||||
|
$var as = [[$for j, [[get<$j>(args)]]]]
|
||||||
|
$range k 1..n-i
|
||||||
|
$var eas = [[$for k, [[ExcessiveArg()]]]]
|
||||||
|
$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]]
|
||||||
|
$template
|
||||||
|
static Result Perform(Impl* impl, const ::std::tr1::tuple<$As>& args) {
|
||||||
|
using ::std::tr1::get;
|
||||||
|
return impl->template gmock_PerformImpl<$As>(args, $arg_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
|
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
|
||||||
|
// the selected arguments of the mock function to an_action and
|
||||||
|
// performs it. It serves as an adaptor between actions with
|
||||||
|
// different argument lists. C++ doesn't support default arguments for
|
||||||
|
// function templates, so we have to overload it.
|
||||||
|
|
||||||
|
$range i 1..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
template <$for j [[int k$j, ]]typename InnerAction>
|
||||||
|
inline internal::WithArgsAction<InnerAction$for j [[, k$j]]>
|
||||||
|
WithArgs(const InnerAction& action) {
|
||||||
|
return internal::WithArgsAction<InnerAction$for j [[, k$j]]>(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
// Creates an action that does actions a1, a2, ..., sequentially in
|
||||||
|
// each invocation.
|
||||||
|
$range i 2..n
|
||||||
|
$for i [[
|
||||||
|
$range j 2..i
|
||||||
|
$var types = [[$for j, [[typename Action$j]]]]
|
||||||
|
$var Aas = [[$for j [[, Action$j a$j]]]]
|
||||||
|
|
||||||
|
template <typename Action1, $types>
|
||||||
|
$range k 1..i-1
|
||||||
|
|
||||||
|
inline $for k [[internal::DoBothAction<Action$k, ]]Action$i$for k [[>]]
|
||||||
|
|
||||||
|
DoAll(Action1 a1$Aas) {
|
||||||
|
$if i==2 [[
|
||||||
|
|
||||||
|
return internal::DoBothAction<Action1, Action2>(a1, a2);
|
||||||
|
]] $else [[
|
||||||
|
$range j2 2..i
|
||||||
|
|
||||||
|
return DoAll(a1, DoAll($for j2, [[a$j2]]));
|
||||||
|
]]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
// The ACTION* family of macros can be used in a namespace scope to
|
||||||
|
// define custom actions easily. The syntax:
|
||||||
|
//
|
||||||
|
// ACTION(name) { statements; }
|
||||||
|
//
|
||||||
|
// will define an action with the given name that executes the
|
||||||
|
// statements. The value returned by the statements will be used as
|
||||||
|
// the return value of the action. Inside the statements, you can
|
||||||
|
// refer to the K-th (0-based) argument of the mock function by
|
||||||
|
// 'argK', and refer to its type by 'argK_type'. For example:
|
||||||
|
//
|
||||||
|
// ACTION(IncrementArg1) {
|
||||||
|
// arg1_type temp = arg1;
|
||||||
|
// return ++(*temp);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// allows you to write
|
||||||
|
//
|
||||||
|
// ...WillOnce(IncrementArg1());
|
||||||
|
//
|
||||||
|
// You can also refer to the entire argument tuple and its type by
|
||||||
|
// 'args' and 'args_type', and refer to the mock function type and its
|
||||||
|
// return type by 'function_type' and 'return_type'.
|
||||||
|
//
|
||||||
|
// Note that you don't need to specify the types of the mock function
|
||||||
|
// arguments. However rest assured that your code is still type-safe:
|
||||||
|
// you'll get a compiler error if *arg1 doesn't support the ++
|
||||||
|
// operator, or if the type of ++(*arg1) isn't compatible with the
|
||||||
|
// mock function's return type, for example.
|
||||||
|
//
|
||||||
|
// Sometimes you'll want to parameterize the action. For that you can use
|
||||||
|
// another macro:
|
||||||
|
//
|
||||||
|
// ACTION_P(name, param_name) { statements; }
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// ACTION_P(Add, n) { return arg0 + n; }
|
||||||
|
//
|
||||||
|
// will allow you to write:
|
||||||
|
//
|
||||||
|
// ...WillOnce(Add(5));
|
||||||
|
//
|
||||||
|
// Note that you don't need to provide the type of the parameter
|
||||||
|
// either. If you need to reference the type of a parameter named
|
||||||
|
// 'foo', you can write 'foo_type'. For example, in the body of
|
||||||
|
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type
|
||||||
|
// of 'n'.
|
||||||
|
//
|
||||||
|
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support
|
||||||
|
// multi-parameter actions.
|
||||||
|
//
|
||||||
|
// For the purpose of typing, you can view
|
||||||
|
//
|
||||||
|
// ACTION_Pk(Foo, p1, ..., pk) { ... }
|
||||||
|
//
|
||||||
|
// as shorthand for
|
||||||
|
//
|
||||||
|
// template <typename p1_type, ..., typename pk_type>
|
||||||
|
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... }
|
||||||
|
//
|
||||||
|
// In particular, you can provide the template type arguments
|
||||||
|
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false);
|
||||||
|
// although usually you can rely on the compiler to infer the types
|
||||||
|
// for you automatically. You can assign the result of expression
|
||||||
|
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ...,
|
||||||
|
// pk_type>. This can be useful when composing actions.
|
||||||
|
//
|
||||||
|
// You can also overload actions with different numbers of parameters:
|
||||||
|
//
|
||||||
|
// ACTION_P(Plus, a) { ... }
|
||||||
|
// ACTION_P2(Plus, a, b) { ... }
|
||||||
|
//
|
||||||
|
// While it's tempting to always use the ACTION* macros when defining
|
||||||
|
// a new action, you should also consider implementing ActionInterface
|
||||||
|
// or using MakePolymorphicAction() instead, especially if you need to
|
||||||
|
// use the action a lot. While these approaches require more work,
|
||||||
|
// they give you more control on the types of the mock function
|
||||||
|
// arguments and the action parameters, which in general leads to
|
||||||
|
// better compiler error messages that pay off in the long run. They
|
||||||
|
// also allow overloading actions based on parameter types (as opposed
|
||||||
|
// to just based on the number of parameters).
|
||||||
|
//
|
||||||
|
// CAVEAT:
|
||||||
|
//
|
||||||
|
// ACTION*() can only be used in a namespace scope. The reason is
|
||||||
|
// that C++ doesn't yet allow function-local types to be used to
|
||||||
|
// instantiate templates. The up-coming C++0x standard will fix this.
|
||||||
|
// Once that's done, we'll consider supporting using ACTION*() inside
|
||||||
|
// a function.
|
||||||
|
//
|
||||||
|
// MORE INFORMATION:
|
||||||
|
//
|
||||||
|
// To learn more about using these macros, please search for 'ACTION'
|
||||||
|
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$range k 0..n-1
|
||||||
|
|
||||||
|
// An internal macro needed for implementing ACTION*().
|
||||||
|
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
|
||||||
|
const args_type& args GTEST_ATTRIBUTE_UNUSED_
|
||||||
|
$for k [[, \
|
||||||
|
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
|
||||||
|
|
||||||
|
|
||||||
|
// Sometimes you want to give an action explicit template parameters
|
||||||
|
// that cannot be inferred from its value parameters. ACTION() and
|
||||||
|
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that
|
||||||
|
// and can be viewed as an extension to ACTION() and ACTION_P*().
|
||||||
|
//
|
||||||
|
// The syntax:
|
||||||
|
//
|
||||||
|
// ACTION_TEMPLATE(ActionName,
|
||||||
|
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
|
||||||
|
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
|
||||||
|
//
|
||||||
|
// defines an action template that takes m explicit template
|
||||||
|
// parameters and n value parameters. name_i is the name of the i-th
|
||||||
|
// template parameter, and kind_i specifies whether it's a typename,
|
||||||
|
// an integral constant, or a template. p_i is the name of the i-th
|
||||||
|
// value parameter.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock
|
||||||
|
// // function to type T and copies it to *output.
|
||||||
|
// ACTION_TEMPLATE(DuplicateArg,
|
||||||
|
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
|
||||||
|
// AND_1_VALUE_PARAMS(output)) {
|
||||||
|
// *output = T(std::tr1::get<k>(args));
|
||||||
|
// }
|
||||||
|
// ...
|
||||||
|
// int n;
|
||||||
|
// EXPECT_CALL(mock, Foo(_, _))
|
||||||
|
// .WillOnce(DuplicateArg<1, unsigned char>(&n));
|
||||||
|
//
|
||||||
|
// To create an instance of an action template, write:
|
||||||
|
//
|
||||||
|
// ActionName<t1, ..., t_m>(v1, ..., v_n)
|
||||||
|
//
|
||||||
|
// where the ts are the template arguments and the vs are the value
|
||||||
|
// arguments. The value argument types are inferred by the compiler.
|
||||||
|
// If you want to explicitly specify the value argument types, you can
|
||||||
|
// provide additional template arguments:
|
||||||
|
//
|
||||||
|
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
|
||||||
|
//
|
||||||
|
// where u_i is the desired type of v_i.
|
||||||
|
//
|
||||||
|
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the
|
||||||
|
// number of value parameters, but not on the number of template
|
||||||
|
// parameters. Without the restriction, the meaning of the following
|
||||||
|
// is unclear:
|
||||||
|
//
|
||||||
|
// OverloadedAction<int, bool>(x);
|
||||||
|
//
|
||||||
|
// Are we using a single-template-parameter action where 'bool' refers
|
||||||
|
// to the type of x, or are we using a two-template-parameter action
|
||||||
|
// where the compiler is asked to infer the type of x?
|
||||||
|
//
|
||||||
|
// Implementation notes:
|
||||||
|
//
|
||||||
|
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and
|
||||||
|
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for
|
||||||
|
// implementing ACTION_TEMPLATE. The main trick we use is to create
|
||||||
|
// new macro invocations when expanding a macro. For example, we have
|
||||||
|
//
|
||||||
|
// #define ACTION_TEMPLATE(name, template_params, value_params)
|
||||||
|
// ... GMOCK_INTERNAL_DECL_##template_params ...
|
||||||
|
//
|
||||||
|
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...)
|
||||||
|
// to expand to
|
||||||
|
//
|
||||||
|
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ...
|
||||||
|
//
|
||||||
|
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the
|
||||||
|
// preprocessor will continue to expand it to
|
||||||
|
//
|
||||||
|
// ... typename T ...
|
||||||
|
//
|
||||||
|
// This technique conforms to the C++ standard and is portable. It
|
||||||
|
// allows us to implement action templates using O(N) code, where N is
|
||||||
|
// the maximum number of template/value parameters supported. Without
|
||||||
|
// using it, we'd have to devote O(N^2) amount of code to implement all
|
||||||
|
// combinations of m and n.
|
||||||
|
|
||||||
|
// Declares the template parameters.
|
||||||
|
|
||||||
|
$range j 1..n
|
||||||
|
$for j [[
|
||||||
|
$range m 0..j-1
|
||||||
|
#define GMOCK_INTERNAL_DECL_HAS_$j[[]]
|
||||||
|
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Lists the template parameters.
|
||||||
|
|
||||||
|
$for j [[
|
||||||
|
$range m 0..j-1
|
||||||
|
#define GMOCK_INTERNAL_LIST_HAS_$j[[]]
|
||||||
|
_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Declares the types of value parameters.
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]]
|
||||||
|
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Initializes the value parameters.
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\
|
||||||
|
($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Declares the fields for storing the value parameters.
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
#define GMOCK_INTERNAL_DEFN_AND_$i[[]]
|
||||||
|
_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Lists the value parameters.
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
#define GMOCK_INTERNAL_LIST_AND_$i[[]]
|
||||||
|
_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Lists the value parameter types.
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]]
|
||||||
|
_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Declares the value parameters.
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||||
|
$for j, [[p$j##_type p$j]]
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// The suffix of the class template implementing the action template.
|
||||||
|
$for i [[
|
||||||
|
|
||||||
|
|
||||||
|
$range j 0..i-1
|
||||||
|
#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]]
|
||||||
|
$if i==1 [[P]] $elif i>=2 [[P$i]]
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
// The name of the class template implementing the action template.
|
||||||
|
#define GMOCK_ACTION_CLASS_(name, value_params)\
|
||||||
|
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params)
|
||||||
|
|
||||||
|
$range k 0..n-1
|
||||||
|
|
||||||
|
#define ACTION_TEMPLATE(name, template_params, value_params)\
|
||||||
|
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||||
|
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||||
|
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
||||||
|
public:\
|
||||||
|
GMOCK_ACTION_CLASS_(name, value_params)\
|
||||||
|
GMOCK_INTERNAL_INIT_##value_params {}\
|
||||||
|
template <typename F>\
|
||||||
|
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||||
|
public:\
|
||||||
|
typedef F function_type;\
|
||||||
|
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
||||||
|
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
||||||
|
args_type;\
|
||||||
|
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
|
||||||
|
virtual return_type Perform(const args_type& args) {\
|
||||||
|
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
||||||
|
Perform(this, args);\
|
||||||
|
}\
|
||||||
|
template <$for k, [[typename arg$k[[]]_type]]>\
|
||||||
|
return_type gmock_PerformImpl(const args_type& args[[]]
|
||||||
|
$for k [[, arg$k[[]]_type arg$k]]) const;\
|
||||||
|
GMOCK_INTERNAL_DEFN_##value_params\
|
||||||
|
private:\
|
||||||
|
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||||
|
};\
|
||||||
|
template <typename F> operator ::testing::Action<F>() const {\
|
||||||
|
return ::testing::Action<F>(\
|
||||||
|
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
|
||||||
|
}\
|
||||||
|
GMOCK_INTERNAL_DEFN_##value_params\
|
||||||
|
private:\
|
||||||
|
GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\
|
||||||
|
};\
|
||||||
|
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||||
|
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||||
|
inline GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||||
|
GMOCK_INTERNAL_LIST_##template_params\
|
||||||
|
GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\
|
||||||
|
GMOCK_INTERNAL_DECL_##value_params) {\
|
||||||
|
return GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||||
|
GMOCK_INTERNAL_LIST_##template_params\
|
||||||
|
GMOCK_INTERNAL_LIST_TYPE_##value_params>(\
|
||||||
|
GMOCK_INTERNAL_LIST_##value_params);\
|
||||||
|
}\
|
||||||
|
template <GMOCK_INTERNAL_DECL_##template_params\
|
||||||
|
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||||
|
template <typename F>\
|
||||||
|
template <typename arg0_type, typename arg1_type, typename arg2_type, \
|
||||||
|
typename arg3_type, typename arg4_type, typename arg5_type, \
|
||||||
|
typename arg6_type, typename arg7_type, typename arg8_type, \
|
||||||
|
typename arg9_type>\
|
||||||
|
typename ::testing::internal::Function<F>::Result\
|
||||||
|
GMOCK_ACTION_CLASS_(name, value_params)<\
|
||||||
|
GMOCK_INTERNAL_LIST_##template_params\
|
||||||
|
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl<F>::\
|
||||||
|
gmock_PerformImpl(\
|
||||||
|
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||||
|
|
||||||
|
$for i
|
||||||
|
|
||||||
|
[[
|
||||||
|
$var template = [[$if i==0 [[]] $else [[
|
||||||
|
$range j 0..i-1
|
||||||
|
|
||||||
|
template <$for j, [[typename p$j##_type]]>\
|
||||||
|
]]]]
|
||||||
|
$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]]
|
||||||
|
$else [[P$i]]]]]]
|
||||||
|
$range j 0..i-1
|
||||||
|
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||||
|
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||||
|
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||||
|
$var param_field_decls = [[$for j
|
||||||
|
[[
|
||||||
|
|
||||||
|
p$j##_type p$j;\
|
||||||
|
]]]]
|
||||||
|
$var param_field_decls2 = [[$for j
|
||||||
|
[[
|
||||||
|
|
||||||
|
p$j##_type p$j;\
|
||||||
|
]]]]
|
||||||
|
$var params = [[$for j, [[p$j]]]]
|
||||||
|
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||||
|
$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]]
|
||||||
|
$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]]
|
||||||
|
$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
|
||||||
|
$else [[ACTION_P$i]]]]
|
||||||
|
|
||||||
|
#define $macro_name(name$for j [[, p$j]])\$template
|
||||||
|
class $class_name {\
|
||||||
|
public:\
|
||||||
|
$class_name($ctor_param_list)$inits {}\
|
||||||
|
template <typename F>\
|
||||||
|
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||||
|
public:\
|
||||||
|
typedef F function_type;\
|
||||||
|
typedef typename ::testing::internal::Function<F>::Result return_type;\
|
||||||
|
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
|
||||||
|
args_type;\
|
||||||
|
[[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
|
||||||
|
virtual return_type Perform(const args_type& args) {\
|
||||||
|
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
|
||||||
|
Perform(this, args);\
|
||||||
|
}\
|
||||||
|
template <$typename_arg_types>\
|
||||||
|
return_type gmock_PerformImpl(const args_type& args, [[]]
|
||||||
|
$arg_types_and_names) const;\$param_field_decls
|
||||||
|
private:\
|
||||||
|
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||||
|
};\
|
||||||
|
template <typename F> operator ::testing::Action<F>() const {\
|
||||||
|
return ::testing::Action<F>(new gmock_Impl<F>($params));\
|
||||||
|
}\$param_field_decls2
|
||||||
|
private:\
|
||||||
|
GTEST_DISALLOW_ASSIGN_($class_name);\
|
||||||
|
};\$template
|
||||||
|
inline $class_name$param_types name($param_types_and_names) {\
|
||||||
|
return $class_name$param_types($params);\
|
||||||
|
}\$template
|
||||||
|
template <typename F>\
|
||||||
|
template <$typename_arg_types>\
|
||||||
|
typename ::testing::internal::Function<F>::Result\
|
||||||
|
$class_name$param_types::gmock_Impl<F>::gmock_PerformImpl(\
|
||||||
|
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
|
||||||
|
]]
|
||||||
|
$$ } // This meta comment fixes auto-indentation in Emacs. It won't
|
||||||
|
$$ // show up in the generated code.
|
||||||
|
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||||
|
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||||
|
// the macro definition, as the warnings are generated when the macro
|
||||||
|
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||||
|
// we suppress them here.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4100)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Various overloads for InvokeArgument<N>().
|
||||||
|
//
|
||||||
|
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
|
||||||
|
// (0-based) argument, which must be a k-ary callable, of the mock
|
||||||
|
// function, with arguments a1, a2, ..., a_k.
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
//
|
||||||
|
// 1. The arguments are passed by value by default. If you need to
|
||||||
|
// pass an argument by reference, wrap it inside ByRef(). For
|
||||||
|
// example,
|
||||||
|
//
|
||||||
|
// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
|
||||||
|
//
|
||||||
|
// passes 5 and string("Hello") by value, and passes foo by
|
||||||
|
// reference.
|
||||||
|
//
|
||||||
|
// 2. If the callable takes an argument by reference but ByRef() is
|
||||||
|
// not used, it will receive the reference to a copy of the value,
|
||||||
|
// instead of the original value. For example, when the 0-th
|
||||||
|
// argument of the mock function takes a const string&, the action
|
||||||
|
//
|
||||||
|
// InvokeArgument<0>(string("Hello"))
|
||||||
|
//
|
||||||
|
// makes a copy of the temporary string("Hello") object and passes a
|
||||||
|
// reference of the copy, instead of the original temporary object,
|
||||||
|
// to the callable. This makes it easy for a user to define an
|
||||||
|
// InvokeArgument action from temporary values and have it performed
|
||||||
|
// later.
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
|
||||||
|
ACTION_TEMPLATE(InvokeArgument,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
|
AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) {
|
||||||
|
return internal::CallableHelper<return_type>::Call(
|
||||||
|
::std::tr1::get<k>(args)$for j [[, p$j]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// Various overloads for ReturnNew<T>().
|
||||||
|
//
|
||||||
|
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
|
||||||
|
// instance of type T, constructed on the heap with constructor arguments
|
||||||
|
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
$var ps = [[$for j, [[p$j]]]]
|
||||||
|
|
||||||
|
ACTION_TEMPLATE(ReturnNew,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||||
|
AND_$i[[]]_VALUE_PARAMS($ps)) {
|
||||||
|
return new T($ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
|
||||||
991
gmock/include/gmock/gmock-generated-function-mockers.h
Normal file
991
gmock/include/gmock/gmock-generated-function-mockers.h
Normal file
@@ -0,0 +1,991 @@
|
|||||||
|
// This file was GENERATED by command:
|
||||||
|
// pump.py gmock-generated-function-mockers.h.pump
|
||||||
|
// DO NOT EDIT BY HAND!!!
|
||||||
|
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements function mockers of various arities.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
|
|
||||||
|
#include "gmock/gmock-spec-builders.h"
|
||||||
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
class FunctionMockerBase;
|
||||||
|
|
||||||
|
// Note: class FunctionMocker really belongs to the ::testing
|
||||||
|
// namespace. However if we define it in ::testing, MSVC will
|
||||||
|
// complain when classes in ::testing::internal declare it as a
|
||||||
|
// friend class template. To workaround this compiler bug, we define
|
||||||
|
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||||
|
template <typename F>
|
||||||
|
class FunctionMocker;
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
class FunctionMocker<R()> : public
|
||||||
|
internal::FunctionMockerBase<R()> {
|
||||||
|
public:
|
||||||
|
typedef R F();
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With() {
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke() {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1>
|
||||||
|
class FunctionMocker<R(A1)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2>
|
||||||
|
class FunctionMocker<R(A1, A2)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3>
|
||||||
|
class FunctionMocker<R(A1, A2, A3)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||||
|
class FunctionMocker<R(A1, A2, A3, A4)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3, A4);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3, const Matcher<A4>& m4) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5>
|
||||||
|
class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3, A4, A5);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4,
|
||||||
|
m5));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6>
|
||||||
|
class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3, A4, A5, A6);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||||
|
const Matcher<A6>& m6) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||||
|
m6));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7>
|
||||||
|
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3, A4, A5, A6, A7);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||||
|
const Matcher<A6>& m6, const Matcher<A7>& m7) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||||
|
m6, m7));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7, typename A8>
|
||||||
|
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||||
|
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||||
|
m6, m7, m8));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||||
|
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||||
|
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||||
|
const Matcher<A9>& m9) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||||
|
m6, m7, m8, m9));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||||
|
typename A10>
|
||||||
|
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
|
||||||
|
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
|
||||||
|
public:
|
||||||
|
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||||
|
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||||
|
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||||
|
const Matcher<A9>& m9, const Matcher<A10>& m10) {
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5,
|
||||||
|
m6, m7, m8, m9, m10));
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
||||||
|
A10 a10) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9,
|
||||||
|
a10));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// The style guide prohibits "using" statements in a namespace scope
|
||||||
|
// inside a header file. However, the FunctionMocker class template
|
||||||
|
// is meant to be defined in the ::testing namespace. The following
|
||||||
|
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||||
|
// cannot handle it if we define FunctionMocker in ::testing.
|
||||||
|
using internal::FunctionMocker;
|
||||||
|
|
||||||
|
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
|
||||||
|
// We define this as a variadic macro in case F contains unprotected
|
||||||
|
// commas (the same reason that we use variadic macros in other places
|
||||||
|
// in this file).
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_RESULT_(tn, ...) \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::Result
|
||||||
|
|
||||||
|
// The type of argument N of the given function type.
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_ARG_(tn, N, ...) \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
|
||||||
|
|
||||||
|
// The matcher type for argument N of the given function type.
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_MATCHER_(tn, N, ...) \
|
||||||
|
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
|
||||||
|
|
||||||
|
// The variable for mocking the given method.
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||||
|
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 0), \
|
||||||
|
this_method_does_not_take_0_arguments); \
|
||||||
|
GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method() constness { \
|
||||||
|
GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(0, constness, Method).With(); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 1), \
|
||||||
|
this_method_does_not_take_1_argument); \
|
||||||
|
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
|
||||||
|
GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 2), \
|
||||||
|
this_method_does_not_take_2_arguments); \
|
||||||
|
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
|
||||||
|
GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 3), \
|
||||||
|
this_method_does_not_take_3_arguments); \
|
||||||
|
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
|
||||||
|
GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 4), \
|
||||||
|
this_method_does_not_take_4_arguments); \
|
||||||
|
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
|
||||||
|
GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 5), \
|
||||||
|
this_method_does_not_take_5_arguments); \
|
||||||
|
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
|
||||||
|
GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 6), \
|
||||||
|
this_method_does_not_take_6_arguments); \
|
||||||
|
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
|
||||||
|
GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 7), \
|
||||||
|
this_method_does_not_take_7_arguments); \
|
||||||
|
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
|
||||||
|
GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||||
|
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 8), \
|
||||||
|
this_method_does_not_take_8_arguments); \
|
||||||
|
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||||
|
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
|
||||||
|
GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||||
|
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||||
|
GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 9), \
|
||||||
|
this_method_does_not_take_9_arguments); \
|
||||||
|
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
|
||||||
|
gmock_a9); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||||
|
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||||
|
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
|
||||||
|
GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
|
||||||
|
gmock_a9); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||||
|
GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||||
|
GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
|
||||||
|
GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
|
||||||
|
== 10), \
|
||||||
|
this_method_does_not_take_10_arguments); \
|
||||||
|
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||||
|
gmock_a10); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
|
||||||
|
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
|
||||||
|
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
|
||||||
|
GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
|
||||||
|
GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
|
||||||
|
GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
|
||||||
|
GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
|
||||||
|
GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
|
||||||
|
GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \
|
||||||
|
GMOCK_MATCHER_(tn, 10, \
|
||||||
|
__VA_ARGS__) gmock_a10) constness { \
|
||||||
|
GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
|
||||||
|
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
|
||||||
|
gmock_a10); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
|
||||||
|
Method)
|
||||||
|
|
||||||
|
#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define MOCK_CONST_METHOD0_T(m, ...) \
|
||||||
|
GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD1_T(m, ...) \
|
||||||
|
GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD2_T(m, ...) \
|
||||||
|
GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD3_T(m, ...) \
|
||||||
|
GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD4_T(m, ...) \
|
||||||
|
GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD5_T(m, ...) \
|
||||||
|
GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD6_T(m, ...) \
|
||||||
|
GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD7_T(m, ...) \
|
||||||
|
GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD8_T(m, ...) \
|
||||||
|
GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD9_T(m, ...) \
|
||||||
|
GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD10_T(m, ...) \
|
||||||
|
GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD0_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD1_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD2_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD3_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD4_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD5_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD6_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD7_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD8_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD9_(, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD10_(, , ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
// A MockFunction<F> class has one mock method whose type is F. It is
|
||||||
|
// useful when you just want your test code to emit some messages and
|
||||||
|
// have Google Mock verify the right messages are sent (and perhaps at
|
||||||
|
// the right times). For example, if you are exercising code:
|
||||||
|
//
|
||||||
|
// Foo(1);
|
||||||
|
// Foo(2);
|
||||||
|
// Foo(3);
|
||||||
|
//
|
||||||
|
// and want to verify that Foo(1) and Foo(3) both invoke
|
||||||
|
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
|
||||||
|
//
|
||||||
|
// TEST(FooTest, InvokesBarCorrectly) {
|
||||||
|
// MyMock mock;
|
||||||
|
// MockFunction<void(string check_point_name)> check;
|
||||||
|
// {
|
||||||
|
// InSequence s;
|
||||||
|
//
|
||||||
|
// EXPECT_CALL(mock, Bar("a"));
|
||||||
|
// EXPECT_CALL(check, Call("1"));
|
||||||
|
// EXPECT_CALL(check, Call("2"));
|
||||||
|
// EXPECT_CALL(mock, Bar("a"));
|
||||||
|
// }
|
||||||
|
// Foo(1);
|
||||||
|
// check.Call("1");
|
||||||
|
// Foo(2);
|
||||||
|
// check.Call("2");
|
||||||
|
// Foo(3);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The expectation spec says that the first Bar("a") must happen
|
||||||
|
// before check point "1", the second Bar("a") must happen after check
|
||||||
|
// point "2", and nothing should happen between the two check
|
||||||
|
// points. The explicit check points make it easy to tell which
|
||||||
|
// Bar("a") is called by which call to Foo().
|
||||||
|
template <typename F>
|
||||||
|
class MockFunction;
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
class MockFunction<R()> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD0_T(Call, R());
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0>
|
||||||
|
class MockFunction<R(A0)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD1_T(Call, R(A0));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1>
|
||||||
|
class MockFunction<R(A0, A1)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD2_T(Call, R(A0, A1));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2>
|
||||||
|
class MockFunction<R(A0, A1, A2)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD3_T(Call, R(A0, A1, A2));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2, typename A3>
|
||||||
|
class MockFunction<R(A0, A1, A2, A3)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||||
|
typename A4>
|
||||||
|
class MockFunction<R(A0, A1, A2, A3, A4)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||||
|
typename A4, typename A5>
|
||||||
|
class MockFunction<R(A0, A1, A2, A3, A4, A5)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||||
|
typename A4, typename A5, typename A6>
|
||||||
|
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||||
|
typename A4, typename A5, typename A6, typename A7>
|
||||||
|
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||||
|
typename A4, typename A5, typename A6, typename A7, typename A8>
|
||||||
|
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||||
|
typename A4, typename A5, typename A6, typename A7, typename A8,
|
||||||
|
typename A9>
|
||||||
|
class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
265
gmock/include/gmock/gmock-generated-function-mockers.h.pump
Normal file
265
gmock/include/gmock/gmock-generated-function-mockers.h.pump
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
$$ -*- mode: c++; -*-
|
||||||
|
$$ This is a Pump source file. Please use Pump to convert it to
|
||||||
|
$$ gmock-generated-function-mockers.h.
|
||||||
|
$$
|
||||||
|
$var n = 10 $$ The maximum arity we support.
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements function mockers of various arities.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
|
|
||||||
|
#include "gmock/gmock-spec-builders.h"
|
||||||
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
class FunctionMockerBase;
|
||||||
|
|
||||||
|
// Note: class FunctionMocker really belongs to the ::testing
|
||||||
|
// namespace. However if we define it in ::testing, MSVC will
|
||||||
|
// complain when classes in ::testing::internal declare it as a
|
||||||
|
// friend class template. To workaround this compiler bug, we define
|
||||||
|
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||||
|
template <typename F>
|
||||||
|
class FunctionMocker;
|
||||||
|
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||||
|
$var As = [[$for j, [[A$j]]]]
|
||||||
|
$var as = [[$for j, [[a$j]]]]
|
||||||
|
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||||
|
$var ms = [[$for j, [[m$j]]]]
|
||||||
|
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
|
||||||
|
template <typename R$typename_As>
|
||||||
|
class FunctionMocker<R($As)> : public
|
||||||
|
internal::FunctionMockerBase<R($As)> {
|
||||||
|
public:
|
||||||
|
typedef R F($As);
|
||||||
|
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||||
|
|
||||||
|
MockSpec<F>& With($matchers) {
|
||||||
|
|
||||||
|
$if i >= 1 [[
|
||||||
|
this->current_spec().SetMatchers(::std::tr1::make_tuple($ms));
|
||||||
|
|
||||||
|
]]
|
||||||
|
return this->current_spec();
|
||||||
|
}
|
||||||
|
|
||||||
|
R Invoke($Aas) {
|
||||||
|
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||||
|
// by the C++ standard [14.6.4] here, as the base class type is
|
||||||
|
// dependent on the template argument (and thus shouldn't be
|
||||||
|
// looked into when resolving InvokeWith).
|
||||||
|
return this->InvokeWith(ArgumentTuple($as));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// The style guide prohibits "using" statements in a namespace scope
|
||||||
|
// inside a header file. However, the FunctionMocker class template
|
||||||
|
// is meant to be defined in the ::testing namespace. The following
|
||||||
|
// line is just a trick for working around a bug in MSVC 8.0, which
|
||||||
|
// cannot handle it if we define FunctionMocker in ::testing.
|
||||||
|
using internal::FunctionMocker;
|
||||||
|
|
||||||
|
// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
|
||||||
|
// We define this as a variadic macro in case F contains unprotected
|
||||||
|
// commas (the same reason that we use variadic macros in other places
|
||||||
|
// in this file).
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_RESULT_(tn, ...) \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::Result
|
||||||
|
|
||||||
|
// The type of argument N of the given function type.
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_ARG_(tn, N, ...) \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
|
||||||
|
|
||||||
|
// The matcher type for argument N of the given function type.
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_MATCHER_(tn, N, ...) \
|
||||||
|
const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
|
||||||
|
|
||||||
|
// The variable for mocking the given method.
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_MOCKER_(arity, constness, Method) \
|
||||||
|
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
$var arg_as = [[$for j, \
|
||||||
|
[[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||||
|
$var as = [[$for j, [[gmock_a$j]]]]
|
||||||
|
$var matcher_as = [[$for j, \
|
||||||
|
[[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
|
||||||
|
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
|
||||||
|
#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
|
||||||
|
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
|
||||||
|
$arg_as) constness { \
|
||||||
|
GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \
|
||||||
|
tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
|
||||||
|
this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
|
||||||
|
GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
|
||||||
|
return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
|
||||||
|
} \
|
||||||
|
::testing::MockSpec<__VA_ARGS__>& \
|
||||||
|
gmock_##Method($matcher_as) constness { \
|
||||||
|
GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
|
||||||
|
return GMOCK_MOCKER_($i, constness, Method).With($as); \
|
||||||
|
} \
|
||||||
|
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
|
||||||
|
GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
|
||||||
|
GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// A MockFunction<F> class has one mock method whose type is F. It is
|
||||||
|
// useful when you just want your test code to emit some messages and
|
||||||
|
// have Google Mock verify the right messages are sent (and perhaps at
|
||||||
|
// the right times). For example, if you are exercising code:
|
||||||
|
//
|
||||||
|
// Foo(1);
|
||||||
|
// Foo(2);
|
||||||
|
// Foo(3);
|
||||||
|
//
|
||||||
|
// and want to verify that Foo(1) and Foo(3) both invoke
|
||||||
|
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
|
||||||
|
//
|
||||||
|
// TEST(FooTest, InvokesBarCorrectly) {
|
||||||
|
// MyMock mock;
|
||||||
|
// MockFunction<void(string check_point_name)> check;
|
||||||
|
// {
|
||||||
|
// InSequence s;
|
||||||
|
//
|
||||||
|
// EXPECT_CALL(mock, Bar("a"));
|
||||||
|
// EXPECT_CALL(check, Call("1"));
|
||||||
|
// EXPECT_CALL(check, Call("2"));
|
||||||
|
// EXPECT_CALL(mock, Bar("a"));
|
||||||
|
// }
|
||||||
|
// Foo(1);
|
||||||
|
// check.Call("1");
|
||||||
|
// Foo(2);
|
||||||
|
// check.Call("2");
|
||||||
|
// Foo(3);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The expectation spec says that the first Bar("a") must happen
|
||||||
|
// before check point "1", the second Bar("a") must happen after check
|
||||||
|
// point "2", and nothing should happen between the two check
|
||||||
|
// points. The explicit check points make it easy to tell which
|
||||||
|
// Bar("a") is called by which call to Foo().
|
||||||
|
template <typename F>
|
||||||
|
class MockFunction;
|
||||||
|
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$range j 0..i-1
|
||||||
|
template <typename R$for j [[, typename A$j]]>
|
||||||
|
class MockFunction<R($for j, [[A$j]])> {
|
||||||
|
public:
|
||||||
|
MockFunction() {}
|
||||||
|
|
||||||
|
MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]]));
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||||
2190
gmock/include/gmock/gmock-generated-matchers.h
Normal file
2190
gmock/include/gmock/gmock-generated-matchers.h
Normal file
File diff suppressed because it is too large
Load Diff
674
gmock/include/gmock/gmock-generated-matchers.h.pump
Normal file
674
gmock/include/gmock/gmock-generated-matchers.h.pump
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
$$ -*- mode: c++; -*-
|
||||||
|
$$ This is a Pump source file. Please use Pump to convert it to
|
||||||
|
$$ gmock-generated-actions.h.
|
||||||
|
$$
|
||||||
|
$var n = 10 $$ The maximum arity we support.
|
||||||
|
$$ }} This line fixes auto-indentation of the following code in Emacs.
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements some commonly used variadic matchers.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "gmock/gmock-matchers.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
$range i 0..n-1
|
||||||
|
|
||||||
|
// The type of the i-th (0-based) field of Tuple.
|
||||||
|
#define GMOCK_FIELD_TYPE_(Tuple, i) \
|
||||||
|
typename ::std::tr1::tuple_element<i, Tuple>::type
|
||||||
|
|
||||||
|
// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
|
||||||
|
// tuple of type Tuple. It has two members:
|
||||||
|
//
|
||||||
|
// type: a tuple type whose i-th field is the ki-th field of Tuple.
|
||||||
|
// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
|
||||||
|
//
|
||||||
|
// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
|
||||||
|
//
|
||||||
|
// type is tuple<int, bool>, and
|
||||||
|
// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
|
||||||
|
|
||||||
|
template <class Tuple$for i [[, int k$i = -1]]>
|
||||||
|
class TupleFields;
|
||||||
|
|
||||||
|
// This generic version is used when there are $n selectors.
|
||||||
|
template <class Tuple$for i [[, int k$i]]>
|
||||||
|
class TupleFields {
|
||||||
|
public:
|
||||||
|
typedef ::std::tr1::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type;
|
||||||
|
static type GetSelectedFields(const Tuple& t) {
|
||||||
|
using ::std::tr1::get;
|
||||||
|
return type($for i, [[get<k$i>(t)]]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The following specialization is used for 0 ~ $(n-1) selectors.
|
||||||
|
|
||||||
|
$for i [[
|
||||||
|
$$ }}}
|
||||||
|
$range j 0..i-1
|
||||||
|
$range k 0..n-1
|
||||||
|
|
||||||
|
template <class Tuple$for j [[, int k$j]]>
|
||||||
|
class TupleFields<Tuple, $for k, [[$if k < i [[k$k]] $else [[-1]]]]> {
|
||||||
|
public:
|
||||||
|
typedef ::std::tr1::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type;
|
||||||
|
static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) {
|
||||||
|
using ::std::tr1::get;
|
||||||
|
return type($for j, [[get<k$j>(t)]]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
#undef GMOCK_FIELD_TYPE_
|
||||||
|
|
||||||
|
// Implements the Args() matcher.
|
||||||
|
|
||||||
|
$var ks = [[$for i, [[k$i]]]]
|
||||||
|
template <class ArgsTuple$for i [[, int k$i = -1]]>
|
||||||
|
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
||||||
|
public:
|
||||||
|
// ArgsTuple may have top-level const or reference modifiers.
|
||||||
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
|
||||||
|
typedef typename internal::TupleFields<RawArgsTuple, $ks>::type SelectedArgs;
|
||||||
|
typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
|
||||||
|
|
||||||
|
template <typename InnerMatcher>
|
||||||
|
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
|
||||||
|
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
|
||||||
|
|
||||||
|
virtual bool MatchAndExplain(ArgsTuple args,
|
||||||
|
MatchResultListener* listener) const {
|
||||||
|
const SelectedArgs& selected_args = GetSelectedArgs(args);
|
||||||
|
if (!listener->IsInterested())
|
||||||
|
return inner_matcher_.Matches(selected_args);
|
||||||
|
|
||||||
|
PrintIndices(listener->stream());
|
||||||
|
*listener << "are " << PrintToString(selected_args);
|
||||||
|
|
||||||
|
StringMatchResultListener inner_listener;
|
||||||
|
const bool match = inner_matcher_.MatchAndExplain(selected_args,
|
||||||
|
&inner_listener);
|
||||||
|
PrintIfNotEmpty(inner_listener.str(), listener->stream());
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DescribeTo(::std::ostream* os) const {
|
||||||
|
*os << "are a tuple ";
|
||||||
|
PrintIndices(os);
|
||||||
|
inner_matcher_.DescribeTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||||
|
*os << "are a tuple ";
|
||||||
|
PrintIndices(os);
|
||||||
|
inner_matcher_.DescribeNegationTo(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static SelectedArgs GetSelectedArgs(ArgsTuple args) {
|
||||||
|
return TupleFields<RawArgsTuple, $ks>::GetSelectedFields(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints the indices of the selected fields.
|
||||||
|
static void PrintIndices(::std::ostream* os) {
|
||||||
|
*os << "whose fields (";
|
||||||
|
const int indices[$n] = { $ks };
|
||||||
|
for (int i = 0; i < $n; i++) {
|
||||||
|
if (indices[i] < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i >= 1)
|
||||||
|
*os << ", ";
|
||||||
|
|
||||||
|
*os << "#" << indices[i];
|
||||||
|
}
|
||||||
|
*os << ") ";
|
||||||
|
}
|
||||||
|
|
||||||
|
const MonomorphicInnerMatcher inner_matcher_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class InnerMatcher$for i [[, int k$i = -1]]>
|
||||||
|
class ArgsMatcher {
|
||||||
|
public:
|
||||||
|
explicit ArgsMatcher(const InnerMatcher& inner_matcher)
|
||||||
|
: inner_matcher_(inner_matcher) {}
|
||||||
|
|
||||||
|
template <typename ArgsTuple>
|
||||||
|
operator Matcher<ArgsTuple>() const {
|
||||||
|
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, $ks>(inner_matcher_));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const InnerMatcher inner_matcher_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
|
||||||
|
};
|
||||||
|
|
||||||
|
// A set of metafunctions for computing the result type of AllOf.
|
||||||
|
// AllOf(m1, ..., mN) returns
|
||||||
|
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
||||||
|
|
||||||
|
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
|
||||||
|
// to simplify the implementation.
|
||||||
|
template <typename M1>
|
||||||
|
struct AllOfResult1 {
|
||||||
|
typedef M1 type;
|
||||||
|
};
|
||||||
|
|
||||||
|
$range i 1..n
|
||||||
|
|
||||||
|
$range i 2..n
|
||||||
|
$for i [[
|
||||||
|
$range j 2..i
|
||||||
|
$var m = i/2
|
||||||
|
$range k 1..m
|
||||||
|
$range t m+1..i
|
||||||
|
|
||||||
|
template <typename M1$for j [[, typename M$j]]>
|
||||||
|
struct AllOfResult$i {
|
||||||
|
typedef BothOfMatcher<
|
||||||
|
typename AllOfResult$m<$for k, [[M$k]]>::type,
|
||||||
|
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// A set of metafunctions for computing the result type of AnyOf.
|
||||||
|
// AnyOf(m1, ..., mN) returns
|
||||||
|
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
|
||||||
|
|
||||||
|
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
|
||||||
|
// to simplify the implementation.
|
||||||
|
template <typename M1>
|
||||||
|
struct AnyOfResult1 {
|
||||||
|
typedef M1 type;
|
||||||
|
};
|
||||||
|
|
||||||
|
$range i 1..n
|
||||||
|
|
||||||
|
$range i 2..n
|
||||||
|
$for i [[
|
||||||
|
$range j 2..i
|
||||||
|
$var m = i/2
|
||||||
|
$range k 1..m
|
||||||
|
$range t m+1..i
|
||||||
|
|
||||||
|
template <typename M1$for j [[, typename M$j]]>
|
||||||
|
struct AnyOfResult$i {
|
||||||
|
typedef EitherOfMatcher<
|
||||||
|
typename AnyOfResult$m<$for k, [[M$k]]>::type,
|
||||||
|
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
|
||||||
|
// fields of it matches a_matcher. C++ doesn't support default
|
||||||
|
// arguments for function templates, so we have to overload it.
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
template <$for j [[int k$j, ]]typename InnerMatcher>
|
||||||
|
inline internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>
|
||||||
|
Args(const InnerMatcher& matcher) {
|
||||||
|
return internal::ArgsMatcher<InnerMatcher$for j [[, k$j]]>(matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
|
||||||
|
// n elements, where the i-th element in the container must
|
||||||
|
// match the i-th argument in the list. Each argument of
|
||||||
|
// ElementsAre() can be either a value or a matcher. We support up to
|
||||||
|
// $n arguments.
|
||||||
|
//
|
||||||
|
// The use of DecayArray in the implementation allows ElementsAre()
|
||||||
|
// to accept string literals, whose type is const char[N], but we
|
||||||
|
// want to treat them as const char*.
|
||||||
|
//
|
||||||
|
// NOTE: Since ElementsAre() cares about the order of the elements, it
|
||||||
|
// must not be used with containers whose elements's order is
|
||||||
|
// undefined (e.g. hash_map).
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
|
||||||
|
$range j 1..i
|
||||||
|
|
||||||
|
$if i>0 [[
|
||||||
|
|
||||||
|
template <$for j, [[typename T$j]]>
|
||||||
|
]]
|
||||||
|
|
||||||
|
inline internal::ElementsAreMatcher<
|
||||||
|
std::tr1::tuple<
|
||||||
|
$for j, [[
|
||||||
|
|
||||||
|
typename internal::DecayArray<T$j[[]]>::type]]> >
|
||||||
|
ElementsAre($for j, [[const T$j& e$j]]) {
|
||||||
|
typedef std::tr1::tuple<
|
||||||
|
$for j, [[
|
||||||
|
|
||||||
|
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
||||||
|
return internal::ElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
|
||||||
|
// that matches n elements in any order. We support up to n=$n arguments.
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
|
||||||
|
$range j 1..i
|
||||||
|
|
||||||
|
$if i>0 [[
|
||||||
|
|
||||||
|
template <$for j, [[typename T$j]]>
|
||||||
|
]]
|
||||||
|
|
||||||
|
inline internal::UnorderedElementsAreMatcher<
|
||||||
|
std::tr1::tuple<
|
||||||
|
$for j, [[
|
||||||
|
|
||||||
|
typename internal::DecayArray<T$j[[]]>::type]]> >
|
||||||
|
UnorderedElementsAre($for j, [[const T$j& e$j]]) {
|
||||||
|
typedef std::tr1::tuple<
|
||||||
|
$for j, [[
|
||||||
|
|
||||||
|
typename internal::DecayArray<T$j[[]]>::type]]> Args;
|
||||||
|
return internal::UnorderedElementsAreMatcher<Args>(Args($for j, [[e$j]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
|
||||||
|
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
|
||||||
|
|
||||||
|
$range i 2..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
$var m = i/2
|
||||||
|
$range k 1..m
|
||||||
|
$range t m+1..i
|
||||||
|
|
||||||
|
template <$for j, [[typename M$j]]>
|
||||||
|
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
|
||||||
|
AllOf($for j, [[M$j m$j]]) {
|
||||||
|
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
|
||||||
|
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
|
||||||
|
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
|
||||||
|
// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing.
|
||||||
|
|
||||||
|
$range i 2..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
$var m = i/2
|
||||||
|
$range k 1..m
|
||||||
|
$range t m+1..i
|
||||||
|
|
||||||
|
template <$for j, [[typename M$j]]>
|
||||||
|
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
|
||||||
|
AnyOf($for j, [[M$j m$j]]) {
|
||||||
|
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
|
||||||
|
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
|
||||||
|
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not
|
||||||
|
$$ // show up in the generated code.
|
||||||
|
|
||||||
|
|
||||||
|
// The MATCHER* family of macros can be used in a namespace scope to
|
||||||
|
// define custom matchers easily.
|
||||||
|
//
|
||||||
|
// Basic Usage
|
||||||
|
// ===========
|
||||||
|
//
|
||||||
|
// The syntax
|
||||||
|
//
|
||||||
|
// MATCHER(name, description_string) { statements; }
|
||||||
|
//
|
||||||
|
// defines a matcher with the given name that executes the statements,
|
||||||
|
// which must return a bool to indicate if the match succeeds. Inside
|
||||||
|
// the statements, you can refer to the value being matched by 'arg',
|
||||||
|
// and refer to its type by 'arg_type'.
|
||||||
|
//
|
||||||
|
// The description string documents what the matcher does, and is used
|
||||||
|
// to generate the failure message when the match fails. Since a
|
||||||
|
// MATCHER() is usually defined in a header file shared by multiple
|
||||||
|
// C++ source files, we require the description to be a C-string
|
||||||
|
// literal to avoid possible side effects. It can be empty, in which
|
||||||
|
// case we'll use the sequence of words in the matcher name as the
|
||||||
|
// description.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
|
||||||
|
//
|
||||||
|
// allows you to write
|
||||||
|
//
|
||||||
|
// // Expects mock_foo.Bar(n) to be called where n is even.
|
||||||
|
// EXPECT_CALL(mock_foo, Bar(IsEven()));
|
||||||
|
//
|
||||||
|
// or,
|
||||||
|
//
|
||||||
|
// // Verifies that the value of some_expression is even.
|
||||||
|
// EXPECT_THAT(some_expression, IsEven());
|
||||||
|
//
|
||||||
|
// If the above assertion fails, it will print something like:
|
||||||
|
//
|
||||||
|
// Value of: some_expression
|
||||||
|
// Expected: is even
|
||||||
|
// Actual: 7
|
||||||
|
//
|
||||||
|
// where the description "is even" is automatically calculated from the
|
||||||
|
// matcher name IsEven.
|
||||||
|
//
|
||||||
|
// Argument Type
|
||||||
|
// =============
|
||||||
|
//
|
||||||
|
// Note that the type of the value being matched (arg_type) is
|
||||||
|
// determined by the context in which you use the matcher and is
|
||||||
|
// supplied to you by the compiler, so you don't need to worry about
|
||||||
|
// declaring it (nor can you). This allows the matcher to be
|
||||||
|
// polymorphic. For example, IsEven() can be used to match any type
|
||||||
|
// where the value of "(arg % 2) == 0" can be implicitly converted to
|
||||||
|
// a bool. In the "Bar(IsEven())" example above, if method Bar()
|
||||||
|
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
|
||||||
|
// 'arg_type' will be unsigned long; and so on.
|
||||||
|
//
|
||||||
|
// Parameterizing Matchers
|
||||||
|
// =======================
|
||||||
|
//
|
||||||
|
// Sometimes you'll want to parameterize the matcher. For that you
|
||||||
|
// can use another macro:
|
||||||
|
//
|
||||||
|
// MATCHER_P(name, param_name, description_string) { statements; }
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
|
||||||
|
//
|
||||||
|
// will allow you to write:
|
||||||
|
//
|
||||||
|
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
|
||||||
|
//
|
||||||
|
// which may lead to this message (assuming n is 10):
|
||||||
|
//
|
||||||
|
// Value of: Blah("a")
|
||||||
|
// Expected: has absolute value 10
|
||||||
|
// Actual: -9
|
||||||
|
//
|
||||||
|
// Note that both the matcher description and its parameter are
|
||||||
|
// printed, making the message human-friendly.
|
||||||
|
//
|
||||||
|
// In the matcher definition body, you can write 'foo_type' to
|
||||||
|
// reference the type of a parameter named 'foo'. For example, in the
|
||||||
|
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
|
||||||
|
// 'value_type' to refer to the type of 'value'.
|
||||||
|
//
|
||||||
|
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
|
||||||
|
// support multi-parameter matchers.
|
||||||
|
//
|
||||||
|
// Describing Parameterized Matchers
|
||||||
|
// =================================
|
||||||
|
//
|
||||||
|
// The last argument to MATCHER*() is a string-typed expression. The
|
||||||
|
// expression can reference all of the matcher's parameters and a
|
||||||
|
// special bool-typed variable named 'negation'. When 'negation' is
|
||||||
|
// false, the expression should evaluate to the matcher's description;
|
||||||
|
// otherwise it should evaluate to the description of the negation of
|
||||||
|
// the matcher. For example,
|
||||||
|
//
|
||||||
|
// using testing::PrintToString;
|
||||||
|
//
|
||||||
|
// MATCHER_P2(InClosedRange, low, hi,
|
||||||
|
// string(negation ? "is not" : "is") + " in range [" +
|
||||||
|
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
|
||||||
|
// return low <= arg && arg <= hi;
|
||||||
|
// }
|
||||||
|
// ...
|
||||||
|
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||||
|
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
|
||||||
|
//
|
||||||
|
// would generate two failures that contain the text:
|
||||||
|
//
|
||||||
|
// Expected: is in range [4, 6]
|
||||||
|
// ...
|
||||||
|
// Expected: is not in range [2, 4]
|
||||||
|
//
|
||||||
|
// If you specify "" as the description, the failure message will
|
||||||
|
// contain the sequence of words in the matcher name followed by the
|
||||||
|
// parameter values printed as a tuple. For example,
|
||||||
|
//
|
||||||
|
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
|
||||||
|
// ...
|
||||||
|
// EXPECT_THAT(3, InClosedRange(4, 6));
|
||||||
|
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
|
||||||
|
//
|
||||||
|
// would generate two failures that contain the text:
|
||||||
|
//
|
||||||
|
// Expected: in closed range (4, 6)
|
||||||
|
// ...
|
||||||
|
// Expected: not (in closed range (2, 4))
|
||||||
|
//
|
||||||
|
// Types of Matcher Parameters
|
||||||
|
// ===========================
|
||||||
|
//
|
||||||
|
// For the purpose of typing, you can view
|
||||||
|
//
|
||||||
|
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
|
||||||
|
//
|
||||||
|
// as shorthand for
|
||||||
|
//
|
||||||
|
// template <typename p1_type, ..., typename pk_type>
|
||||||
|
// FooMatcherPk<p1_type, ..., pk_type>
|
||||||
|
// Foo(p1_type p1, ..., pk_type pk) { ... }
|
||||||
|
//
|
||||||
|
// When you write Foo(v1, ..., vk), the compiler infers the types of
|
||||||
|
// the parameters v1, ..., and vk for you. If you are not happy with
|
||||||
|
// the result of the type inference, you can specify the types by
|
||||||
|
// explicitly instantiating the template, as in Foo<long, bool>(5,
|
||||||
|
// false). As said earlier, you don't get to (or need to) specify
|
||||||
|
// 'arg_type' as that's determined by the context in which the matcher
|
||||||
|
// is used. You can assign the result of expression Foo(p1, ..., pk)
|
||||||
|
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
|
||||||
|
// can be useful when composing matchers.
|
||||||
|
//
|
||||||
|
// While you can instantiate a matcher template with reference types,
|
||||||
|
// passing the parameters by pointer usually makes your code more
|
||||||
|
// readable. If, however, you still want to pass a parameter by
|
||||||
|
// reference, be aware that in the failure message generated by the
|
||||||
|
// matcher you will see the value of the referenced object but not its
|
||||||
|
// address.
|
||||||
|
//
|
||||||
|
// Explaining Match Results
|
||||||
|
// ========================
|
||||||
|
//
|
||||||
|
// Sometimes the matcher description alone isn't enough to explain why
|
||||||
|
// the match has failed or succeeded. For example, when expecting a
|
||||||
|
// long string, it can be very helpful to also print the diff between
|
||||||
|
// the expected string and the actual one. To achieve that, you can
|
||||||
|
// optionally stream additional information to a special variable
|
||||||
|
// named result_listener, whose type is a pointer to class
|
||||||
|
// MatchResultListener:
|
||||||
|
//
|
||||||
|
// MATCHER_P(EqualsLongString, str, "") {
|
||||||
|
// if (arg == str) return true;
|
||||||
|
//
|
||||||
|
// *result_listener << "the difference: "
|
||||||
|
/// << DiffStrings(str, arg);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Overloading Matchers
|
||||||
|
// ====================
|
||||||
|
//
|
||||||
|
// You can overload matchers with different numbers of parameters:
|
||||||
|
//
|
||||||
|
// MATCHER_P(Blah, a, description_string1) { ... }
|
||||||
|
// MATCHER_P2(Blah, a, b, description_string2) { ... }
|
||||||
|
//
|
||||||
|
// Caveats
|
||||||
|
// =======
|
||||||
|
//
|
||||||
|
// When defining a new matcher, you should also consider implementing
|
||||||
|
// MatcherInterface or using MakePolymorphicMatcher(). These
|
||||||
|
// approaches require more work than the MATCHER* macros, but also
|
||||||
|
// give you more control on the types of the value being matched and
|
||||||
|
// the matcher parameters, which may leads to better compiler error
|
||||||
|
// messages when the matcher is used wrong. They also allow
|
||||||
|
// overloading matchers based on parameter types (as opposed to just
|
||||||
|
// based on the number of parameters).
|
||||||
|
//
|
||||||
|
// MATCHER*() can only be used in a namespace scope. The reason is
|
||||||
|
// that C++ doesn't yet allow function-local types to be used to
|
||||||
|
// instantiate templates. The up-coming C++0x standard will fix this.
|
||||||
|
// Once that's done, we'll consider supporting using MATCHER*() inside
|
||||||
|
// a function.
|
||||||
|
//
|
||||||
|
// More Information
|
||||||
|
// ================
|
||||||
|
//
|
||||||
|
// To learn more about using these macros, please search for 'MATCHER'
|
||||||
|
// on http://code.google.com/p/googlemock/wiki/CookBook.
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i
|
||||||
|
|
||||||
|
[[
|
||||||
|
$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]]
|
||||||
|
$else [[MATCHER_P$i]]]]
|
||||||
|
$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]]
|
||||||
|
$else [[P$i]]]]]]
|
||||||
|
$range j 0..i-1
|
||||||
|
$var template = [[$if i==0 [[]] $else [[
|
||||||
|
|
||||||
|
template <$for j, [[typename p$j##_type]]>\
|
||||||
|
]]]]
|
||||||
|
$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||||
|
$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]]
|
||||||
|
$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||||
|
$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]]
|
||||||
|
$var params = [[$for j, [[p$j]]]]
|
||||||
|
$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]]
|
||||||
|
$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]]
|
||||||
|
$var param_field_decls = [[$for j
|
||||||
|
[[
|
||||||
|
|
||||||
|
p$j##_type p$j;\
|
||||||
|
]]]]
|
||||||
|
$var param_field_decls2 = [[$for j
|
||||||
|
[[
|
||||||
|
|
||||||
|
p$j##_type p$j;\
|
||||||
|
]]]]
|
||||||
|
|
||||||
|
#define $macro_name(name$for j [[, p$j]], description)\$template
|
||||||
|
class $class_name {\
|
||||||
|
public:\
|
||||||
|
template <typename arg_type>\
|
||||||
|
class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
|
||||||
|
public:\
|
||||||
|
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
|
||||||
|
$impl_inits {}\
|
||||||
|
virtual bool MatchAndExplain(\
|
||||||
|
arg_type arg, ::testing::MatchResultListener* result_listener) const;\
|
||||||
|
virtual void DescribeTo(::std::ostream* gmock_os) const {\
|
||||||
|
*gmock_os << FormatDescription(false);\
|
||||||
|
}\
|
||||||
|
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
|
||||||
|
*gmock_os << FormatDescription(true);\
|
||||||
|
}\$param_field_decls
|
||||||
|
private:\
|
||||||
|
::testing::internal::string FormatDescription(bool negation) const {\
|
||||||
|
const ::testing::internal::string gmock_description = (description);\
|
||||||
|
if (!gmock_description.empty())\
|
||||||
|
return gmock_description;\
|
||||||
|
return ::testing::internal::FormatMatcherDescription(\
|
||||||
|
negation, #name, \
|
||||||
|
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
|
||||||
|
::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
|
||||||
|
}\
|
||||||
|
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
|
||||||
|
};\
|
||||||
|
template <typename arg_type>\
|
||||||
|
operator ::testing::Matcher<arg_type>() const {\
|
||||||
|
return ::testing::Matcher<arg_type>(\
|
||||||
|
new gmock_Impl<arg_type>($params));\
|
||||||
|
}\
|
||||||
|
$class_name($ctor_param_list)$inits {\
|
||||||
|
}\$param_field_decls2
|
||||||
|
private:\
|
||||||
|
GTEST_DISALLOW_ASSIGN_($class_name);\
|
||||||
|
};\$template
|
||||||
|
inline $class_name$param_types name($param_types_and_names) {\
|
||||||
|
return $class_name$param_types($params);\
|
||||||
|
}\$template
|
||||||
|
template <typename arg_type>\
|
||||||
|
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
|
||||||
|
arg_type arg, \
|
||||||
|
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
|
||||||
|
const
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
|
||||||
397
gmock/include/gmock/gmock-generated-nice-strict.h
Normal file
397
gmock/include/gmock/gmock-generated-nice-strict.h
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
// This file was GENERATED by command:
|
||||||
|
// pump.py gmock-generated-nice-strict.h.pump
|
||||||
|
// DO NOT EDIT BY HAND!!!
|
||||||
|
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Implements class templates NiceMock, NaggyMock, and StrictMock.
|
||||||
|
//
|
||||||
|
// Given a mock class MockFoo that is created using Google Mock,
|
||||||
|
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||||
|
// uninteresting calls (i.e. calls to mock methods that have no
|
||||||
|
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||||
|
// that prints a warning when an uninteresting call occurs, and
|
||||||
|
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||||
|
// uninteresting calls as errors.
|
||||||
|
//
|
||||||
|
// Currently a mock is naggy by default, so MockFoo and
|
||||||
|
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||||
|
// switch the default behavior of mocks to be nice, as that in general
|
||||||
|
// leads to more maintainable tests. When that happens, MockFoo will
|
||||||
|
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||||
|
// NiceMock<MockFoo>.
|
||||||
|
//
|
||||||
|
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
||||||
|
// their respective base class, with up-to 10 arguments. Therefore
|
||||||
|
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
|
||||||
|
// where MockFoo has a constructor that accepts (int, const char*),
|
||||||
|
// for example.
|
||||||
|
//
|
||||||
|
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
|
||||||
|
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||||
|
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||||
|
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||||
|
// or "strict" modifier may not affect it, depending on the compiler.
|
||||||
|
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||||
|
// supported.
|
||||||
|
//
|
||||||
|
// Another known limitation is that the constructors of the base mock
|
||||||
|
// cannot have arguments passed by non-const reference, which are
|
||||||
|
// banned by the Google C++ style guide anyway.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||||
|
|
||||||
|
#include "gmock/gmock-spec-builders.h"
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
template <class MockClass>
|
||||||
|
class NiceMock : public MockClass {
|
||||||
|
public:
|
||||||
|
// We don't factor out the constructor body to a common method, as
|
||||||
|
// we have to avoid a possible clash with members of MockClass.
|
||||||
|
NiceMock() {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||||
|
// to define it for each arity.
|
||||||
|
template <typename A1>
|
||||||
|
explicit NiceMock(const A1& a1) : MockClass(a1) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
template <typename A1, typename A2>
|
||||||
|
NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3,
|
||||||
|
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||||
|
a6, a7) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||||
|
a2, a3, a4, a5, a6, a7, a8) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||||
|
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||||
|
NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||||
|
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||||
|
::testing::Mock::AllowUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~NiceMock() {
|
||||||
|
::testing::Mock::UnregisterCallReaction(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class MockClass>
|
||||||
|
class NaggyMock : public MockClass {
|
||||||
|
public:
|
||||||
|
// We don't factor out the constructor body to a common method, as
|
||||||
|
// we have to avoid a possible clash with members of MockClass.
|
||||||
|
NaggyMock() {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||||
|
// to define it for each arity.
|
||||||
|
template <typename A1>
|
||||||
|
explicit NaggyMock(const A1& a1) : MockClass(a1) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
template <typename A1, typename A2>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3,
|
||||||
|
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||||
|
a6, a7) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||||
|
a2, a3, a4, a5, a6, a7, a8) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||||
|
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||||
|
NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||||
|
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||||
|
::testing::Mock::WarnUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~NaggyMock() {
|
||||||
|
::testing::Mock::UnregisterCallReaction(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class MockClass>
|
||||||
|
class StrictMock : public MockClass {
|
||||||
|
public:
|
||||||
|
// We don't factor out the constructor body to a common method, as
|
||||||
|
// we have to avoid a possible clash with members of MockClass.
|
||||||
|
StrictMock() {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||||
|
// to define it for each arity.
|
||||||
|
template <typename A1>
|
||||||
|
explicit StrictMock(const A1& a1) : MockClass(a1) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
template <typename A1, typename A2>
|
||||||
|
StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3,
|
||||||
|
const A4& a4) : MockClass(a1, a2, a3, a4) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
|
||||||
|
a6, a7) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
|
||||||
|
a2, a3, a4, a5, a6, a7, a8) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8,
|
||||||
|
const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||||
|
StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
|
||||||
|
const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
|
||||||
|
const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
|
||||||
|
::testing::Mock::FailUninterestingCalls(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~StrictMock() {
|
||||||
|
::testing::Mock::UnregisterCallReaction(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
|
||||||
|
};
|
||||||
|
|
||||||
|
// The following specializations catch some (relatively more common)
|
||||||
|
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||||
|
// all possible errors.
|
||||||
|
|
||||||
|
// These specializations are declared but not defined, as NiceMock,
|
||||||
|
// NaggyMock, and StrictMock cannot be nested.
|
||||||
|
|
||||||
|
template <typename MockClass>
|
||||||
|
class NiceMock<NiceMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NiceMock<NaggyMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NiceMock<StrictMock<MockClass> >;
|
||||||
|
|
||||||
|
template <typename MockClass>
|
||||||
|
class NaggyMock<NiceMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NaggyMock<NaggyMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NaggyMock<StrictMock<MockClass> >;
|
||||||
|
|
||||||
|
template <typename MockClass>
|
||||||
|
class StrictMock<NiceMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class StrictMock<NaggyMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class StrictMock<StrictMock<MockClass> >;
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||||
161
gmock/include/gmock/gmock-generated-nice-strict.h.pump
Normal file
161
gmock/include/gmock/gmock-generated-nice-strict.h.pump
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
$$ -*- mode: c++; -*-
|
||||||
|
$$ This is a Pump source file. Please use Pump to convert it to
|
||||||
|
$$ gmock-generated-nice-strict.h.
|
||||||
|
$$
|
||||||
|
$var n = 10 $$ The maximum arity we support.
|
||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Implements class templates NiceMock, NaggyMock, and StrictMock.
|
||||||
|
//
|
||||||
|
// Given a mock class MockFoo that is created using Google Mock,
|
||||||
|
// NiceMock<MockFoo> is a subclass of MockFoo that allows
|
||||||
|
// uninteresting calls (i.e. calls to mock methods that have no
|
||||||
|
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
|
||||||
|
// that prints a warning when an uninteresting call occurs, and
|
||||||
|
// StrictMock<MockFoo> is a subclass of MockFoo that treats all
|
||||||
|
// uninteresting calls as errors.
|
||||||
|
//
|
||||||
|
// Currently a mock is naggy by default, so MockFoo and
|
||||||
|
// NaggyMock<MockFoo> behave like the same. However, we will soon
|
||||||
|
// switch the default behavior of mocks to be nice, as that in general
|
||||||
|
// leads to more maintainable tests. When that happens, MockFoo will
|
||||||
|
// stop behaving like NaggyMock<MockFoo> and start behaving like
|
||||||
|
// NiceMock<MockFoo>.
|
||||||
|
//
|
||||||
|
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
|
||||||
|
// their respective base class, with up-to $n arguments. Therefore
|
||||||
|
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
|
||||||
|
// where MockFoo has a constructor that accepts (int, const char*),
|
||||||
|
// for example.
|
||||||
|
//
|
||||||
|
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
|
||||||
|
// and StrictMock<MockFoo> only works for mock methods defined using
|
||||||
|
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
|
||||||
|
// If a mock method is defined in a base class of MockFoo, the "nice"
|
||||||
|
// or "strict" modifier may not affect it, depending on the compiler.
|
||||||
|
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
|
||||||
|
// supported.
|
||||||
|
//
|
||||||
|
// Another known limitation is that the constructors of the base mock
|
||||||
|
// cannot have arguments passed by non-const reference, which are
|
||||||
|
// banned by the Google C++ style guide anyway.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||||
|
|
||||||
|
#include "gmock/gmock-spec-builders.h"
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
$range kind 0..2
|
||||||
|
$for kind [[
|
||||||
|
|
||||||
|
$var clazz=[[$if kind==0 [[NiceMock]]
|
||||||
|
$elif kind==1 [[NaggyMock]]
|
||||||
|
$else [[StrictMock]]]]
|
||||||
|
|
||||||
|
$var method=[[$if kind==0 [[AllowUninterestingCalls]]
|
||||||
|
$elif kind==1 [[WarnUninterestingCalls]]
|
||||||
|
$else [[FailUninterestingCalls]]]]
|
||||||
|
|
||||||
|
template <class MockClass>
|
||||||
|
class $clazz : public MockClass {
|
||||||
|
public:
|
||||||
|
// We don't factor out the constructor body to a common method, as
|
||||||
|
// we have to avoid a possible clash with members of MockClass.
|
||||||
|
$clazz() {
|
||||||
|
::testing::Mock::$method(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// C++ doesn't (yet) allow inheritance of constructors, so we have
|
||||||
|
// to define it for each arity.
|
||||||
|
template <typename A1>
|
||||||
|
explicit $clazz(const A1& a1) : MockClass(a1) {
|
||||||
|
::testing::Mock::$method(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
$range i 2..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
template <$for j, [[typename A$j]]>
|
||||||
|
$clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) {
|
||||||
|
::testing::Mock::$method(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
virtual ~$clazz() {
|
||||||
|
::testing::Mock::UnregisterCallReaction(
|
||||||
|
internal::ImplicitCast_<MockClass*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz);
|
||||||
|
};
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
// The following specializations catch some (relatively more common)
|
||||||
|
// user errors of nesting nice and strict mocks. They do NOT catch
|
||||||
|
// all possible errors.
|
||||||
|
|
||||||
|
// These specializations are declared but not defined, as NiceMock,
|
||||||
|
// NaggyMock, and StrictMock cannot be nested.
|
||||||
|
|
||||||
|
template <typename MockClass>
|
||||||
|
class NiceMock<NiceMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NiceMock<NaggyMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NiceMock<StrictMock<MockClass> >;
|
||||||
|
|
||||||
|
template <typename MockClass>
|
||||||
|
class NaggyMock<NiceMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NaggyMock<NaggyMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class NaggyMock<StrictMock<MockClass> >;
|
||||||
|
|
||||||
|
template <typename MockClass>
|
||||||
|
class StrictMock<NiceMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class StrictMock<NaggyMock<MockClass> >;
|
||||||
|
template <typename MockClass>
|
||||||
|
class StrictMock<StrictMock<MockClass> >;
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
|
||||||
3986
gmock/include/gmock/gmock-matchers.h
Normal file
3986
gmock/include/gmock/gmock-matchers.h
Normal file
File diff suppressed because it is too large
Load Diff
233
gmock/include/gmock/gmock-more-actions.h
Normal file
233
gmock/include/gmock/gmock-more-actions.h
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements some actions that depend on gmock-generated-actions.h.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "gmock/gmock-generated-actions.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Implements the Invoke(f) action. The template argument
|
||||||
|
// FunctionImpl is the implementation type of f, which can be either a
|
||||||
|
// function pointer or a functor. Invoke(f) can be used as an
|
||||||
|
// Action<F> as long as f's type is compatible with F (i.e. f can be
|
||||||
|
// assigned to a tr1::function<F>).
|
||||||
|
template <typename FunctionImpl>
|
||||||
|
class InvokeAction {
|
||||||
|
public:
|
||||||
|
// The c'tor makes a copy of function_impl (either a function
|
||||||
|
// pointer or a functor).
|
||||||
|
explicit InvokeAction(FunctionImpl function_impl)
|
||||||
|
: function_impl_(function_impl) {}
|
||||||
|
|
||||||
|
template <typename Result, typename ArgumentTuple>
|
||||||
|
Result Perform(const ArgumentTuple& args) {
|
||||||
|
return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FunctionImpl function_impl_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(InvokeAction);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implements the Invoke(object_ptr, &Class::Method) action.
|
||||||
|
template <class Class, typename MethodPtr>
|
||||||
|
class InvokeMethodAction {
|
||||||
|
public:
|
||||||
|
InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
|
||||||
|
: obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
|
||||||
|
|
||||||
|
template <typename Result, typename ArgumentTuple>
|
||||||
|
Result Perform(const ArgumentTuple& args) const {
|
||||||
|
return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
|
||||||
|
obj_ptr_, method_ptr_, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Class* const obj_ptr_;
|
||||||
|
const MethodPtr method_ptr_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Various overloads for Invoke().
|
||||||
|
|
||||||
|
// Creates an action that invokes 'function_impl' with the mock
|
||||||
|
// function's arguments.
|
||||||
|
template <typename FunctionImpl>
|
||||||
|
PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
|
||||||
|
FunctionImpl function_impl) {
|
||||||
|
return MakePolymorphicAction(
|
||||||
|
internal::InvokeAction<FunctionImpl>(function_impl));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an action that invokes the given method on the given object
|
||||||
|
// with the mock function's arguments.
|
||||||
|
template <class Class, typename MethodPtr>
|
||||||
|
PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
|
||||||
|
Class* obj_ptr, MethodPtr method_ptr) {
|
||||||
|
return MakePolymorphicAction(
|
||||||
|
internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithoutArgs(inner_action) can be used in a mock function with a
|
||||||
|
// non-empty argument list to perform inner_action, which takes no
|
||||||
|
// argument. In other words, it adapts an action accepting no
|
||||||
|
// argument to one that accepts (and ignores) arguments.
|
||||||
|
template <typename InnerAction>
|
||||||
|
inline internal::WithArgsAction<InnerAction>
|
||||||
|
WithoutArgs(const InnerAction& action) {
|
||||||
|
return internal::WithArgsAction<InnerAction>(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithArg<k>(an_action) creates an action that passes the k-th
|
||||||
|
// (0-based) argument of the mock function to an_action and performs
|
||||||
|
// it. It adapts an action accepting one argument to one that accepts
|
||||||
|
// multiple arguments. For convenience, we also provide
|
||||||
|
// WithArgs<k>(an_action) (defined below) as a synonym.
|
||||||
|
template <int k, typename InnerAction>
|
||||||
|
inline internal::WithArgsAction<InnerAction, k>
|
||||||
|
WithArg(const InnerAction& action) {
|
||||||
|
return internal::WithArgsAction<InnerAction, k>(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The ACTION*() macros trigger warning C4100 (unreferenced formal
|
||||||
|
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
|
||||||
|
// the macro definition, as the warnings are generated when the macro
|
||||||
|
// is expanded and macro expansion cannot contain #pragma. Therefore
|
||||||
|
// we suppress them here.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4100)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Action ReturnArg<k>() returns the k-th argument of the mock function.
|
||||||
|
ACTION_TEMPLATE(ReturnArg,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
|
AND_0_VALUE_PARAMS()) {
|
||||||
|
return std::tr1::get<k>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
|
||||||
|
// mock function to *pointer.
|
||||||
|
ACTION_TEMPLATE(SaveArg,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
|
AND_1_VALUE_PARAMS(pointer)) {
|
||||||
|
*pointer = ::std::tr1::get<k>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action SaveArgPointee<k>(pointer) saves the value pointed to
|
||||||
|
// by the k-th (0-based) argument of the mock function to *pointer.
|
||||||
|
ACTION_TEMPLATE(SaveArgPointee,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
|
AND_1_VALUE_PARAMS(pointer)) {
|
||||||
|
*pointer = *::std::tr1::get<k>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action SetArgReferee<k>(value) assigns 'value' to the variable
|
||||||
|
// referenced by the k-th (0-based) argument of the mock function.
|
||||||
|
ACTION_TEMPLATE(SetArgReferee,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
|
AND_1_VALUE_PARAMS(value)) {
|
||||||
|
typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
|
||||||
|
// Ensures that argument #k is a reference. If you get a compiler
|
||||||
|
// error on the next line, you are using SetArgReferee<k>(value) in
|
||||||
|
// a mock function whose k-th (0-based) argument is not a reference.
|
||||||
|
GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
|
||||||
|
SetArgReferee_must_be_used_with_a_reference_argument);
|
||||||
|
::std::tr1::get<k>(args) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action SetArrayArgument<k>(first, last) copies the elements in
|
||||||
|
// source range [first, last) to the array pointed to by the k-th
|
||||||
|
// (0-based) argument, which can be either a pointer or an
|
||||||
|
// iterator. The action does not take ownership of the elements in the
|
||||||
|
// source range.
|
||||||
|
ACTION_TEMPLATE(SetArrayArgument,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
|
AND_2_VALUE_PARAMS(first, last)) {
|
||||||
|
// Microsoft compiler deprecates ::std::copy, so we want to suppress warning
|
||||||
|
// 4996 (Function call with parameters that may be unsafe) there.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||||
|
#endif
|
||||||
|
::std::copy(first, last, ::std::tr1::get<k>(args));
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
|
||||||
|
// function.
|
||||||
|
ACTION_TEMPLATE(DeleteArg,
|
||||||
|
HAS_1_TEMPLATE_PARAMS(int, k),
|
||||||
|
AND_0_VALUE_PARAMS()) {
|
||||||
|
delete ::std::tr1::get<k>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This action returns the value pointed to by 'pointer'.
|
||||||
|
ACTION_P(ReturnPointee, pointer) { return *pointer; }
|
||||||
|
|
||||||
|
// Action Throw(exception) can be used in a mock function of any type
|
||||||
|
// to throw the given exception. Any copyable value can be thrown.
|
||||||
|
#if GTEST_HAS_EXCEPTIONS
|
||||||
|
|
||||||
|
// Suppresses the 'unreachable code' warning that VC generates in opt modes.
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# pragma warning(push) // Saves the current warning state.
|
||||||
|
# pragma warning(disable:4702) // Temporarily disables warning 4702.
|
||||||
|
# endif
|
||||||
|
ACTION_P(Throw, exception) { throw exception; }
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif // GTEST_HAS_EXCEPTIONS
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
|
||||||
58
gmock/include/gmock/gmock-more-matchers.h
Normal file
58
gmock/include/gmock/gmock-more-matchers.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2013, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: marcus.boerger@google.com (Marcus Boerger)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements some matchers that depend on gmock-generated-matchers.h.
|
||||||
|
//
|
||||||
|
// Note that tests are implemented in gmock-matchers_test.cc rather than
|
||||||
|
// gmock-more-matchers-test.cc.
|
||||||
|
|
||||||
|
#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||||
|
#define GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||||
|
|
||||||
|
#include "gmock/gmock-generated-matchers.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// Defines a matcher that matches an empty container. The container must
|
||||||
|
// support both size() and empty(), which all STL-like containers provide.
|
||||||
|
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
|
||||||
|
if (arg.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*result_listener << "whose size is " << arg.size();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
|
||||||
1791
gmock/include/gmock/gmock-spec-builders.h
Normal file
1791
gmock/include/gmock/gmock-spec-builders.h
Normal file
File diff suppressed because it is too large
Load Diff
94
gmock/include/gmock/gmock.h
Normal file
94
gmock/include/gmock/gmock.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This is the main header file a user should include.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||||
|
|
||||||
|
// This file implements the following syntax:
|
||||||
|
//
|
||||||
|
// ON_CALL(mock_object.Method(...))
|
||||||
|
// .With(...) ?
|
||||||
|
// .WillByDefault(...);
|
||||||
|
//
|
||||||
|
// where With() is optional and WillByDefault() must appear exactly
|
||||||
|
// once.
|
||||||
|
//
|
||||||
|
// EXPECT_CALL(mock_object.Method(...))
|
||||||
|
// .With(...) ?
|
||||||
|
// .Times(...) ?
|
||||||
|
// .InSequence(...) *
|
||||||
|
// .WillOnce(...) *
|
||||||
|
// .WillRepeatedly(...) ?
|
||||||
|
// .RetiresOnSaturation() ? ;
|
||||||
|
//
|
||||||
|
// where all clauses are optional and WillOnce() can be repeated.
|
||||||
|
|
||||||
|
#include "gmock/gmock-actions.h"
|
||||||
|
#include "gmock/gmock-cardinalities.h"
|
||||||
|
#include "gmock/gmock-generated-actions.h"
|
||||||
|
#include "gmock/gmock-generated-function-mockers.h"
|
||||||
|
#include "gmock/gmock-generated-nice-strict.h"
|
||||||
|
#include "gmock/gmock-generated-matchers.h"
|
||||||
|
#include "gmock/gmock-matchers.h"
|
||||||
|
#include "gmock/gmock-more-actions.h"
|
||||||
|
#include "gmock/gmock-more-matchers.h"
|
||||||
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// Declares Google Mock flags that we want a user to use programmatically.
|
||||||
|
GMOCK_DECLARE_bool_(catch_leaked_mocks);
|
||||||
|
GMOCK_DECLARE_string_(verbose);
|
||||||
|
|
||||||
|
// Initializes Google Mock. This must be called before running the
|
||||||
|
// tests. In particular, it parses the command line for the flags
|
||||||
|
// that Google Mock recognizes. Whenever a Google Mock flag is seen,
|
||||||
|
// it is removed from argv, and *argc is decremented.
|
||||||
|
//
|
||||||
|
// No value is returned. Instead, the Google Mock flag variables are
|
||||||
|
// updated.
|
||||||
|
//
|
||||||
|
// Since Google Test is needed for Google Mock to work, this function
|
||||||
|
// also initializes Google Test and parses its flags, if that hasn't
|
||||||
|
// been done.
|
||||||
|
GTEST_API_ void InitGoogleMock(int* argc, char** argv);
|
||||||
|
|
||||||
|
// This overloaded version can be used in Windows programs compiled in
|
||||||
|
// UNICODE mode.
|
||||||
|
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
|
||||||
279
gmock/include/gmock/internal/gmock-generated-internal-utils.h
Normal file
279
gmock/include/gmock/internal/gmock-generated-internal-utils.h
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
// This file was GENERATED by command:
|
||||||
|
// pump.py gmock-generated-internal-utils.h.pump
|
||||||
|
// DO NOT EDIT BY HAND!!!
|
||||||
|
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file contains template meta-programming utility classes needed
|
||||||
|
// for implementing Google Mock.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||||
|
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Matcher;
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||||
|
// This is used in implementing the IgnoreResult(a) action.
|
||||||
|
class IgnoredValue {
|
||||||
|
public:
|
||||||
|
// This constructor template allows any value to be implicitly
|
||||||
|
// converted to IgnoredValue. The object has no data member and
|
||||||
|
// doesn't try to remember anything about the argument. We
|
||||||
|
// deliberately omit the 'explicit' keyword in order to allow the
|
||||||
|
// conversion to be implicit.
|
||||||
|
template <typename T>
|
||||||
|
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
||||||
|
};
|
||||||
|
|
||||||
|
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||||
|
// for the corresponding field in tuple type T.
|
||||||
|
template <typename Tuple>
|
||||||
|
struct MatcherTuple;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<> > {
|
||||||
|
typedef ::std::tr1::tuple< > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
|
||||||
|
Matcher<A4> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||||
|
Matcher<A5> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||||
|
Matcher<A5>, Matcher<A6> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||||
|
Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||||
|
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||||
|
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename A1, typename A2, typename A3, typename A4, typename A5,
|
||||||
|
typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||||
|
A10> > {
|
||||||
|
typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
|
||||||
|
Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
|
||||||
|
Matcher<A10> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Template struct Function<F>, where F must be a function type, contains
|
||||||
|
// the following typedefs:
|
||||||
|
//
|
||||||
|
// Result: the function's return type.
|
||||||
|
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||||
|
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||||
|
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||||
|
// parameters of F.
|
||||||
|
// MakeResultVoid: the function type obtained by substituting void
|
||||||
|
// for the return type of F.
|
||||||
|
// MakeResultIgnoredValue:
|
||||||
|
// the function type obtained by substituting Something
|
||||||
|
// for the return type of F.
|
||||||
|
template <typename F>
|
||||||
|
struct Function;
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
struct Function<R()> {
|
||||||
|
typedef R Result;
|
||||||
|
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid();
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1>
|
||||||
|
struct Function<R(A1)>
|
||||||
|
: Function<R()> {
|
||||||
|
typedef A1 Argument1;
|
||||||
|
typedef ::std::tr1::tuple<A1> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2>
|
||||||
|
struct Function<R(A1, A2)>
|
||||||
|
: Function<R(A1)> {
|
||||||
|
typedef A2 Argument2;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3>
|
||||||
|
struct Function<R(A1, A2, A3)>
|
||||||
|
: Function<R(A1, A2)> {
|
||||||
|
typedef A3 Argument3;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||||
|
struct Function<R(A1, A2, A3, A4)>
|
||||||
|
: Function<R(A1, A2, A3)> {
|
||||||
|
typedef A4 Argument4;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3, A4> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3, A4);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5>
|
||||||
|
struct Function<R(A1, A2, A3, A4, A5)>
|
||||||
|
: Function<R(A1, A2, A3, A4)> {
|
||||||
|
typedef A5 Argument5;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3, A4, A5);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6>
|
||||||
|
struct Function<R(A1, A2, A3, A4, A5, A6)>
|
||||||
|
: Function<R(A1, A2, A3, A4, A5)> {
|
||||||
|
typedef A6 Argument6;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7>
|
||||||
|
struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
|
||||||
|
: Function<R(A1, A2, A3, A4, A5, A6)> {
|
||||||
|
typedef A7 Argument7;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7, typename A8>
|
||||||
|
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
|
||||||
|
: Function<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||||
|
typedef A8 Argument8;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||||
|
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
|
||||||
|
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||||
|
typedef A9 Argument9;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||||
|
A9);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||||
|
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||||
|
typename A10>
|
||||||
|
struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
|
||||||
|
: Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||||
|
typedef A10 Argument10;
|
||||||
|
typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
|
||||||
|
A10> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
|
||||||
|
A9, A10);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
$$ -*- mode: c++; -*-
|
||||||
|
$$ This is a Pump source file. Please use Pump to convert it to
|
||||||
|
$$ gmock-generated-function-mockers.h.
|
||||||
|
$$
|
||||||
|
$var n = 10 $$ The maximum arity we support.
|
||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file contains template meta-programming utility classes needed
|
||||||
|
// for implementing Google Mock.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||||
|
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Matcher;
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// An IgnoredValue object can be implicitly constructed from ANY value.
|
||||||
|
// This is used in implementing the IgnoreResult(a) action.
|
||||||
|
class IgnoredValue {
|
||||||
|
public:
|
||||||
|
// This constructor template allows any value to be implicitly
|
||||||
|
// converted to IgnoredValue. The object has no data member and
|
||||||
|
// doesn't try to remember anything about the argument. We
|
||||||
|
// deliberately omit the 'explicit' keyword in order to allow the
|
||||||
|
// conversion to be implicit.
|
||||||
|
template <typename T>
|
||||||
|
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
|
||||||
|
};
|
||||||
|
|
||||||
|
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
|
||||||
|
// for the corresponding field in tuple type T.
|
||||||
|
template <typename Tuple>
|
||||||
|
struct MatcherTuple;
|
||||||
|
|
||||||
|
|
||||||
|
$range i 0..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
$var typename_As = [[$for j, [[typename A$j]]]]
|
||||||
|
$var As = [[$for j, [[A$j]]]]
|
||||||
|
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||||
|
template <$typename_As>
|
||||||
|
struct MatcherTuple< ::std::tr1::tuple<$As> > {
|
||||||
|
typedef ::std::tr1::tuple<$matcher_As > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
// Template struct Function<F>, where F must be a function type, contains
|
||||||
|
// the following typedefs:
|
||||||
|
//
|
||||||
|
// Result: the function's return type.
|
||||||
|
// ArgumentN: the type of the N-th argument, where N starts with 1.
|
||||||
|
// ArgumentTuple: the tuple type consisting of all parameters of F.
|
||||||
|
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
|
||||||
|
// parameters of F.
|
||||||
|
// MakeResultVoid: the function type obtained by substituting void
|
||||||
|
// for the return type of F.
|
||||||
|
// MakeResultIgnoredValue:
|
||||||
|
// the function type obtained by substituting Something
|
||||||
|
// for the return type of F.
|
||||||
|
template <typename F>
|
||||||
|
struct Function;
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
struct Function<R()> {
|
||||||
|
typedef R Result;
|
||||||
|
typedef ::std::tr1::tuple<> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid();
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$range i 1..n
|
||||||
|
$for i [[
|
||||||
|
$range j 1..i
|
||||||
|
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||||
|
$var As = [[$for j, [[A$j]]]]
|
||||||
|
$var matcher_As = [[$for j, [[Matcher<A$j>]]]]
|
||||||
|
$range k 1..i-1
|
||||||
|
$var prev_As = [[$for k, [[A$k]]]]
|
||||||
|
template <typename R$typename_As>
|
||||||
|
struct Function<R($As)>
|
||||||
|
: Function<R($prev_As)> {
|
||||||
|
typedef A$i Argument$i;
|
||||||
|
typedef ::std::tr1::tuple<$As> ArgumentTuple;
|
||||||
|
typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
|
||||||
|
typedef void MakeResultVoid($As);
|
||||||
|
typedef IgnoredValue MakeResultIgnoredValue($As);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
|
||||||
498
gmock/include/gmock/internal/gmock-internal-utils.h
Normal file
498
gmock/include/gmock/internal/gmock-internal-utils.h
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file defines some utilities useful for implementing Google
|
||||||
|
// Mock. They are subject to change without notice, so please DO NOT
|
||||||
|
// USE THEM IN USER CODE.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ostream> // NOLINT
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gmock/internal/gmock-generated-internal-utils.h"
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Converts an identifier name to a space-separated list of lower-case
|
||||||
|
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||||
|
// treated as one word. For example, both "FooBar123" and
|
||||||
|
// "foo_bar_123" are converted to "foo bar 123".
|
||||||
|
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
|
||||||
|
|
||||||
|
// PointeeOf<Pointer>::type is the type of a value pointed to by a
|
||||||
|
// Pointer, which can be either a smart pointer or a raw pointer. The
|
||||||
|
// following default implementation is for the case where Pointer is a
|
||||||
|
// smart pointer.
|
||||||
|
template <typename Pointer>
|
||||||
|
struct PointeeOf {
|
||||||
|
// Smart pointer classes define type element_type as the type of
|
||||||
|
// their pointees.
|
||||||
|
typedef typename Pointer::element_type type;
|
||||||
|
};
|
||||||
|
// This specialization is for the raw pointer case.
|
||||||
|
template <typename T>
|
||||||
|
struct PointeeOf<T*> { typedef T type; }; // NOLINT
|
||||||
|
|
||||||
|
// GetRawPointer(p) returns the raw pointer underlying p when p is a
|
||||||
|
// smart pointer, or returns p itself when p is already a raw pointer.
|
||||||
|
// The following default implementation is for the smart pointer case.
|
||||||
|
template <typename Pointer>
|
||||||
|
inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
|
||||||
|
return p.get();
|
||||||
|
}
|
||||||
|
// This overloaded version is for the raw pointer case.
|
||||||
|
template <typename Element>
|
||||||
|
inline Element* GetRawPointer(Element* p) { return p; }
|
||||||
|
|
||||||
|
// This comparator allows linked_ptr to be stored in sets.
|
||||||
|
template <typename T>
|
||||||
|
struct LinkedPtrLessThan {
|
||||||
|
bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
|
||||||
|
const ::testing::internal::linked_ptr<T>& rhs) const {
|
||||||
|
return lhs.get() < rhs.get();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Symbian compilation can be done with wchar_t being either a native
|
||||||
|
// type or a typedef. Using Google Mock with OpenC without wchar_t
|
||||||
|
// should require the definition of _STLP_NO_WCHAR_T.
|
||||||
|
//
|
||||||
|
// MSVC treats wchar_t as a native type usually, but treats it as the
|
||||||
|
// same as unsigned short when the compiler option /Zc:wchar_t- is
|
||||||
|
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
|
||||||
|
// is a native type.
|
||||||
|
#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
|
||||||
|
(defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
|
||||||
|
// wchar_t is a typedef.
|
||||||
|
#else
|
||||||
|
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
|
||||||
|
// Using them is a bad practice and not portable. So DON'T use them.
|
||||||
|
//
|
||||||
|
// Still, Google Mock is designed to work even if the user uses signed
|
||||||
|
// wchar_t or unsigned wchar_t (obviously, assuming the compiler
|
||||||
|
// supports them).
|
||||||
|
//
|
||||||
|
// To gcc,
|
||||||
|
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// signed/unsigned wchar_t are valid types.
|
||||||
|
# define GMOCK_HAS_SIGNED_WCHAR_T_ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// In what follows, we use the term "kind" to indicate whether a type
|
||||||
|
// is bool, an integer type (excluding bool), a floating-point type,
|
||||||
|
// or none of them. This categorization is useful for determining
|
||||||
|
// when a matcher argument type can be safely converted to another
|
||||||
|
// type in the implementation of SafeMatcherCast.
|
||||||
|
enum TypeKind {
|
||||||
|
kBool, kInteger, kFloatingPoint, kOther
|
||||||
|
};
|
||||||
|
|
||||||
|
// KindOf<T>::value is the kind of type T.
|
||||||
|
template <typename T> struct KindOf {
|
||||||
|
enum { value = kOther }; // The default kind.
|
||||||
|
};
|
||||||
|
|
||||||
|
// This macro declares that the kind of 'type' is 'kind'.
|
||||||
|
#define GMOCK_DECLARE_KIND_(type, kind) \
|
||||||
|
template <> struct KindOf<type> { enum { value = kind }; }
|
||||||
|
|
||||||
|
GMOCK_DECLARE_KIND_(bool, kBool);
|
||||||
|
|
||||||
|
// All standard integer types.
|
||||||
|
GMOCK_DECLARE_KIND_(char, kInteger);
|
||||||
|
GMOCK_DECLARE_KIND_(signed char, kInteger);
|
||||||
|
GMOCK_DECLARE_KIND_(unsigned char, kInteger);
|
||||||
|
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
|
||||||
|
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
|
||||||
|
GMOCK_DECLARE_KIND_(int, kInteger);
|
||||||
|
GMOCK_DECLARE_KIND_(unsigned int, kInteger);
|
||||||
|
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
|
||||||
|
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
|
||||||
|
|
||||||
|
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||||
|
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Non-standard integer types.
|
||||||
|
GMOCK_DECLARE_KIND_(Int64, kInteger);
|
||||||
|
GMOCK_DECLARE_KIND_(UInt64, kInteger);
|
||||||
|
|
||||||
|
// All standard floating-point types.
|
||||||
|
GMOCK_DECLARE_KIND_(float, kFloatingPoint);
|
||||||
|
GMOCK_DECLARE_KIND_(double, kFloatingPoint);
|
||||||
|
GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
|
||||||
|
|
||||||
|
#undef GMOCK_DECLARE_KIND_
|
||||||
|
|
||||||
|
// Evaluates to the kind of 'type'.
|
||||||
|
#define GMOCK_KIND_OF_(type) \
|
||||||
|
static_cast< ::testing::internal::TypeKind>( \
|
||||||
|
::testing::internal::KindOf<type>::value)
|
||||||
|
|
||||||
|
// Evaluates to true iff integer type T is signed.
|
||||||
|
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
|
||||||
|
|
||||||
|
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
|
||||||
|
// is true iff arithmetic type From can be losslessly converted to
|
||||||
|
// arithmetic type To.
|
||||||
|
//
|
||||||
|
// It's the user's responsibility to ensure that both From and To are
|
||||||
|
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||||
|
// reference) built-in arithmetic types, kFromKind is the kind of
|
||||||
|
// From, and kToKind is the kind of To; the value is
|
||||||
|
// implementation-defined when the above pre-condition is violated.
|
||||||
|
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
|
||||||
|
struct LosslessArithmeticConvertibleImpl : public false_type {};
|
||||||
|
|
||||||
|
// Converting bool to bool is lossless.
|
||||||
|
template <>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
|
||||||
|
: public true_type {}; // NOLINT
|
||||||
|
|
||||||
|
// Converting bool to any integer type is lossless.
|
||||||
|
template <typename To>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
|
||||||
|
: public true_type {}; // NOLINT
|
||||||
|
|
||||||
|
// Converting bool to any floating-point type is lossless.
|
||||||
|
template <typename To>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
|
||||||
|
: public true_type {}; // NOLINT
|
||||||
|
|
||||||
|
// Converting an integer to bool is lossy.
|
||||||
|
template <typename From>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
|
||||||
|
: public false_type {}; // NOLINT
|
||||||
|
|
||||||
|
// Converting an integer to another non-bool integer is lossless iff
|
||||||
|
// the target type's range encloses the source type's range.
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
|
||||||
|
: public bool_constant<
|
||||||
|
// When converting from a smaller size to a larger size, we are
|
||||||
|
// fine as long as we are not converting from signed to unsigned.
|
||||||
|
((sizeof(From) < sizeof(To)) &&
|
||||||
|
(!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
|
||||||
|
// When converting between the same size, the signedness must match.
|
||||||
|
((sizeof(From) == sizeof(To)) &&
|
||||||
|
(GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
|
||||||
|
|
||||||
|
#undef GMOCK_IS_SIGNED_
|
||||||
|
|
||||||
|
// Converting an integer to a floating-point type may be lossy, since
|
||||||
|
// the format of a floating-point number is implementation-defined.
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
|
||||||
|
: public false_type {}; // NOLINT
|
||||||
|
|
||||||
|
// Converting a floating-point to bool is lossy.
|
||||||
|
template <typename From>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
|
||||||
|
: public false_type {}; // NOLINT
|
||||||
|
|
||||||
|
// Converting a floating-point to an integer is lossy.
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
|
||||||
|
: public false_type {}; // NOLINT
|
||||||
|
|
||||||
|
// Converting a floating-point to another floating-point is lossless
|
||||||
|
// iff the target type is at least as big as the source type.
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct LosslessArithmeticConvertibleImpl<
|
||||||
|
kFloatingPoint, From, kFloatingPoint, To>
|
||||||
|
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
|
||||||
|
|
||||||
|
// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
|
||||||
|
// type From can be losslessly converted to arithmetic type To.
|
||||||
|
//
|
||||||
|
// It's the user's responsibility to ensure that both From and To are
|
||||||
|
// raw (i.e. has no CV modifier, is not a pointer, and is not a
|
||||||
|
// reference) built-in arithmetic types; the value is
|
||||||
|
// implementation-defined when the above pre-condition is violated.
|
||||||
|
template <typename From, typename To>
|
||||||
|
struct LosslessArithmeticConvertible
|
||||||
|
: public LosslessArithmeticConvertibleImpl<
|
||||||
|
GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
|
||||||
|
|
||||||
|
// This interface knows how to report a Google Mock failure (either
|
||||||
|
// non-fatal or fatal).
|
||||||
|
class FailureReporterInterface {
|
||||||
|
public:
|
||||||
|
// The type of a failure (either non-fatal or fatal).
|
||||||
|
enum FailureType {
|
||||||
|
kNonfatal, kFatal
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~FailureReporterInterface() {}
|
||||||
|
|
||||||
|
// Reports a failure that occurred at the given source file location.
|
||||||
|
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||||
|
const string& message) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns the failure reporter used by Google Mock.
|
||||||
|
GTEST_API_ FailureReporterInterface* GetFailureReporter();
|
||||||
|
|
||||||
|
// Asserts that condition is true; aborts the process with the given
|
||||||
|
// message if condition is false. We cannot use LOG(FATAL) or CHECK()
|
||||||
|
// as Google Mock might be used to mock the log sink itself. We
|
||||||
|
// inline this function to prevent it from showing up in the stack
|
||||||
|
// trace.
|
||||||
|
inline void Assert(bool condition, const char* file, int line,
|
||||||
|
const string& msg) {
|
||||||
|
if (!condition) {
|
||||||
|
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
|
||||||
|
file, line, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void Assert(bool condition, const char* file, int line) {
|
||||||
|
Assert(condition, file, line, "Assertion failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies that condition is true; generates a non-fatal failure if
|
||||||
|
// condition is false.
|
||||||
|
inline void Expect(bool condition, const char* file, int line,
|
||||||
|
const string& msg) {
|
||||||
|
if (!condition) {
|
||||||
|
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
|
||||||
|
file, line, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void Expect(bool condition, const char* file, int line) {
|
||||||
|
Expect(condition, file, line, "Expectation failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Severity level of a log.
|
||||||
|
enum LogSeverity {
|
||||||
|
kInfo = 0,
|
||||||
|
kWarning = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Valid values for the --gmock_verbose flag.
|
||||||
|
|
||||||
|
// All logs (informational and warnings) are printed.
|
||||||
|
const char kInfoVerbosity[] = "info";
|
||||||
|
// Only warnings are printed.
|
||||||
|
const char kWarningVerbosity[] = "warning";
|
||||||
|
// No logs are printed.
|
||||||
|
const char kErrorVerbosity[] = "error";
|
||||||
|
|
||||||
|
// Returns true iff a log with the given severity is visible according
|
||||||
|
// to the --gmock_verbose flag.
|
||||||
|
GTEST_API_ bool LogIsVisible(LogSeverity severity);
|
||||||
|
|
||||||
|
// Prints the given message to stdout iff 'severity' >= the level
|
||||||
|
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||||
|
// 0, also prints the stack trace excluding the top
|
||||||
|
// stack_frames_to_skip frames. In opt mode, any positive
|
||||||
|
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||||
|
// function calls will be inlined by the compiler and need to be
|
||||||
|
// conservative.
|
||||||
|
GTEST_API_ void Log(LogSeverity severity,
|
||||||
|
const string& message,
|
||||||
|
int stack_frames_to_skip);
|
||||||
|
|
||||||
|
// TODO(wan@google.com): group all type utilities together.
|
||||||
|
|
||||||
|
// Type traits.
|
||||||
|
|
||||||
|
// is_reference<T>::value is non-zero iff T is a reference type.
|
||||||
|
template <typename T> struct is_reference : public false_type {};
|
||||||
|
template <typename T> struct is_reference<T&> : public true_type {};
|
||||||
|
|
||||||
|
// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
|
||||||
|
template <typename T1, typename T2> struct type_equals : public false_type {};
|
||||||
|
template <typename T> struct type_equals<T, T> : public true_type {};
|
||||||
|
|
||||||
|
// remove_reference<T>::type removes the reference from type T, if any.
|
||||||
|
template <typename T> struct remove_reference { typedef T type; }; // NOLINT
|
||||||
|
template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
|
||||||
|
|
||||||
|
// DecayArray<T>::type turns an array type U[N] to const U* and preserves
|
||||||
|
// other types. Useful for saving a copy of a function argument.
|
||||||
|
template <typename T> struct DecayArray { typedef T type; }; // NOLINT
|
||||||
|
template <typename T, size_t N> struct DecayArray<T[N]> {
|
||||||
|
typedef const T* type;
|
||||||
|
};
|
||||||
|
// Sometimes people use arrays whose size is not available at the use site
|
||||||
|
// (e.g. extern const char kNamePrefix[]). This specialization covers that
|
||||||
|
// case.
|
||||||
|
template <typename T> struct DecayArray<T[]> {
|
||||||
|
typedef const T* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invalid<T>() returns an invalid value of type T. This is useful
|
||||||
|
// when a value of type T is needed for compilation, but the statement
|
||||||
|
// will not really be executed (or we don't care if the statement
|
||||||
|
// crashes).
|
||||||
|
template <typename T>
|
||||||
|
inline T Invalid() {
|
||||||
|
return const_cast<typename remove_reference<T>::type&>(
|
||||||
|
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
inline void Invalid<void>() {}
|
||||||
|
|
||||||
|
// Given a raw type (i.e. having no top-level reference or const
|
||||||
|
// modifier) RawContainer that's either an STL-style container or a
|
||||||
|
// native array, class StlContainerView<RawContainer> has the
|
||||||
|
// following members:
|
||||||
|
//
|
||||||
|
// - type is a type that provides an STL-style container view to
|
||||||
|
// (i.e. implements the STL container concept for) RawContainer;
|
||||||
|
// - const_reference is a type that provides a reference to a const
|
||||||
|
// RawContainer;
|
||||||
|
// - ConstReference(raw_container) returns a const reference to an STL-style
|
||||||
|
// container view to raw_container, which is a RawContainer.
|
||||||
|
// - Copy(raw_container) returns an STL-style container view of a
|
||||||
|
// copy of raw_container, which is a RawContainer.
|
||||||
|
//
|
||||||
|
// This generic version is used when RawContainer itself is already an
|
||||||
|
// STL-style container.
|
||||||
|
template <class RawContainer>
|
||||||
|
class StlContainerView {
|
||||||
|
public:
|
||||||
|
typedef RawContainer type;
|
||||||
|
typedef const type& const_reference;
|
||||||
|
|
||||||
|
static const_reference ConstReference(const RawContainer& container) {
|
||||||
|
// Ensures that RawContainer is not a const type.
|
||||||
|
testing::StaticAssertTypeEq<RawContainer,
|
||||||
|
GTEST_REMOVE_CONST_(RawContainer)>();
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
static type Copy(const RawContainer& container) { return container; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// This specialization is used when RawContainer is a native array type.
|
||||||
|
template <typename Element, size_t N>
|
||||||
|
class StlContainerView<Element[N]> {
|
||||||
|
public:
|
||||||
|
typedef GTEST_REMOVE_CONST_(Element) RawElement;
|
||||||
|
typedef internal::NativeArray<RawElement> type;
|
||||||
|
// NativeArray<T> can represent a native array either by value or by
|
||||||
|
// reference (selected by a constructor argument), so 'const type'
|
||||||
|
// can be used to reference a const native array. We cannot
|
||||||
|
// 'typedef const type& const_reference' here, as that would mean
|
||||||
|
// ConstReference() has to return a reference to a local variable.
|
||||||
|
typedef const type const_reference;
|
||||||
|
|
||||||
|
static const_reference ConstReference(const Element (&array)[N]) {
|
||||||
|
// Ensures that Element is not a const type.
|
||||||
|
testing::StaticAssertTypeEq<Element, RawElement>();
|
||||||
|
#if GTEST_OS_SYMBIAN
|
||||||
|
// The Nokia Symbian compiler confuses itself in template instantiation
|
||||||
|
// for this call without the cast to Element*:
|
||||||
|
// function call '[testing::internal::NativeArray<char *>].NativeArray(
|
||||||
|
// {lval} const char *[4], long, testing::internal::RelationToSource)'
|
||||||
|
// does not match
|
||||||
|
// 'testing::internal::NativeArray<char *>::NativeArray(
|
||||||
|
// char *const *, unsigned int, testing::internal::RelationToSource)'
|
||||||
|
// (instantiating: 'testing::internal::ContainsMatcherImpl
|
||||||
|
// <const char * (&)[4]>::Matches(const char * (&)[4]) const')
|
||||||
|
// (instantiating: 'testing::internal::StlContainerView<char *[4]>::
|
||||||
|
// ConstReference(const char * (&)[4])')
|
||||||
|
// (and though the N parameter type is mismatched in the above explicit
|
||||||
|
// conversion of it doesn't help - only the conversion of the array).
|
||||||
|
return type(const_cast<Element*>(&array[0]), N, kReference);
|
||||||
|
#else
|
||||||
|
return type(array, N, kReference);
|
||||||
|
#endif // GTEST_OS_SYMBIAN
|
||||||
|
}
|
||||||
|
static type Copy(const Element (&array)[N]) {
|
||||||
|
#if GTEST_OS_SYMBIAN
|
||||||
|
return type(const_cast<Element*>(&array[0]), N, kCopy);
|
||||||
|
#else
|
||||||
|
return type(array, N, kCopy);
|
||||||
|
#endif // GTEST_OS_SYMBIAN
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This specialization is used when RawContainer is a native array
|
||||||
|
// represented as a (pointer, size) tuple.
|
||||||
|
template <typename ElementPointer, typename Size>
|
||||||
|
class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
|
||||||
|
public:
|
||||||
|
typedef GTEST_REMOVE_CONST_(
|
||||||
|
typename internal::PointeeOf<ElementPointer>::type) RawElement;
|
||||||
|
typedef internal::NativeArray<RawElement> type;
|
||||||
|
typedef const type const_reference;
|
||||||
|
|
||||||
|
static const_reference ConstReference(
|
||||||
|
const ::std::tr1::tuple<ElementPointer, Size>& array) {
|
||||||
|
using ::std::tr1::get;
|
||||||
|
return type(get<0>(array), get<1>(array), kReference);
|
||||||
|
}
|
||||||
|
static type Copy(const ::std::tr1::tuple<ElementPointer, Size>& array) {
|
||||||
|
using ::std::tr1::get;
|
||||||
|
return type(get<0>(array), get<1>(array), kCopy);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The following specialization prevents the user from instantiating
|
||||||
|
// StlContainer with a reference type.
|
||||||
|
template <typename T> class StlContainerView<T&>;
|
||||||
|
|
||||||
|
// A type transform to remove constness from the first part of a pair.
|
||||||
|
// Pairs like that are used as the value_type of associative containers,
|
||||||
|
// and this transform produces a similar but assignable pair.
|
||||||
|
template <typename T>
|
||||||
|
struct RemoveConstFromKey {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Partially specialized to remove constness from std::pair<const K, V>.
|
||||||
|
template <typename K, typename V>
|
||||||
|
struct RemoveConstFromKey<std::pair<const K, V> > {
|
||||||
|
typedef std::pair<K, V> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
|
||||||
|
// std::integral_constant<bool, kValue>.
|
||||||
|
template <bool kValue>
|
||||||
|
struct BooleanConstant {};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||||
78
gmock/include/gmock/internal/gmock-port.h
Normal file
78
gmock/include/gmock/internal/gmock-port.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: vadimb@google.com (Vadim Berman)
|
||||||
|
//
|
||||||
|
// Low-level types and utilities for porting Google Mock to various
|
||||||
|
// platforms. They are subject to change without notice. DO NOT USE
|
||||||
|
// THEM IN USER CODE.
|
||||||
|
|
||||||
|
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
|
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// Most of the types needed for porting Google Mock are also required
|
||||||
|
// for Google Test and are defined in gtest-port.h.
|
||||||
|
#include "gtest/internal/gtest-linked_ptr.h"
|
||||||
|
#include "gtest/internal/gtest-port.h"
|
||||||
|
|
||||||
|
// To avoid conditional compilation everywhere, we make it
|
||||||
|
// gmock-port.h's responsibility to #include the header implementing
|
||||||
|
// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
|
||||||
|
// guaranteed to pull in the tuple header.
|
||||||
|
|
||||||
|
// For MS Visual C++, check the compiler version. At least VS 2003 is
|
||||||
|
// required to compile Google Mock.
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1310
|
||||||
|
# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Macro for referencing flags. This is public as we want the user to
|
||||||
|
// use this syntax to reference Google Mock flags.
|
||||||
|
#define GMOCK_FLAG(name) FLAGS_gmock_##name
|
||||||
|
|
||||||
|
// Macros for declaring flags.
|
||||||
|
#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
|
||||||
|
#define GMOCK_DECLARE_int32_(name) \
|
||||||
|
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
|
||||||
|
#define GMOCK_DECLARE_string_(name) \
|
||||||
|
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
|
||||||
|
|
||||||
|
// Macros for defining flags.
|
||||||
|
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
|
||||||
|
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
|
||||||
|
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
|
||||||
|
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
|
||||||
|
#define GMOCK_DEFINE_string_(name, default_val, doc) \
|
||||||
|
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
|
||||||
|
|
||||||
|
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
|
||||||
47
gmock/src/gmock-all.cc
Normal file
47
gmock/src/gmock-all.cc
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
//
|
||||||
|
// Google C++ Mocking Framework (Google Mock)
|
||||||
|
//
|
||||||
|
// This file #includes all Google Mock implementation .cc files. The
|
||||||
|
// purpose is to allow a user to build Google Mock by compiling this
|
||||||
|
// file alone.
|
||||||
|
|
||||||
|
// This line ensures that gmock.h can be compiled on its own, even
|
||||||
|
// when it's fused.
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
// The following lines pull in the real gmock *.cc files.
|
||||||
|
#include "src/gmock-cardinalities.cc"
|
||||||
|
#include "src/gmock-internal-utils.cc"
|
||||||
|
#include "src/gmock-matchers.cc"
|
||||||
|
#include "src/gmock-spec-builders.cc"
|
||||||
|
#include "src/gmock.cc"
|
||||||
156
gmock/src/gmock-cardinalities.cc
Normal file
156
gmock/src/gmock-cardinalities.cc
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements cardinalities.
|
||||||
|
|
||||||
|
#include "gmock/gmock-cardinalities.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <ostream> // NOLINT
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Implements the Between(m, n) cardinality.
|
||||||
|
class BetweenCardinalityImpl : public CardinalityInterface {
|
||||||
|
public:
|
||||||
|
BetweenCardinalityImpl(int min, int max)
|
||||||
|
: min_(min >= 0 ? min : 0),
|
||||||
|
max_(max >= min_ ? max : min_) {
|
||||||
|
std::stringstream ss;
|
||||||
|
if (min < 0) {
|
||||||
|
ss << "The invocation lower bound must be >= 0, "
|
||||||
|
<< "but is actually " << min << ".";
|
||||||
|
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||||
|
} else if (max < 0) {
|
||||||
|
ss << "The invocation upper bound must be >= 0, "
|
||||||
|
<< "but is actually " << max << ".";
|
||||||
|
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||||
|
} else if (min > max) {
|
||||||
|
ss << "The invocation upper bound (" << max
|
||||||
|
<< ") must be >= the invocation lower bound (" << min
|
||||||
|
<< ").";
|
||||||
|
internal::Expect(false, __FILE__, __LINE__, ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conservative estimate on the lower/upper bound of the number of
|
||||||
|
// calls allowed.
|
||||||
|
virtual int ConservativeLowerBound() const { return min_; }
|
||||||
|
virtual int ConservativeUpperBound() const { return max_; }
|
||||||
|
|
||||||
|
virtual bool IsSatisfiedByCallCount(int call_count) const {
|
||||||
|
return min_ <= call_count && call_count <= max_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool IsSaturatedByCallCount(int call_count) const {
|
||||||
|
return call_count >= max_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DescribeTo(::std::ostream* os) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int min_;
|
||||||
|
const int max_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Formats "n times" in a human-friendly way.
|
||||||
|
inline internal::string FormatTimes(int n) {
|
||||||
|
if (n == 1) {
|
||||||
|
return "once";
|
||||||
|
} else if (n == 2) {
|
||||||
|
return "twice";
|
||||||
|
} else {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << n << " times";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describes the Between(m, n) cardinality in human-friendly text.
|
||||||
|
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const {
|
||||||
|
if (min_ == 0) {
|
||||||
|
if (max_ == 0) {
|
||||||
|
*os << "never called";
|
||||||
|
} else if (max_ == INT_MAX) {
|
||||||
|
*os << "called any number of times";
|
||||||
|
} else {
|
||||||
|
*os << "called at most " << FormatTimes(max_);
|
||||||
|
}
|
||||||
|
} else if (min_ == max_) {
|
||||||
|
*os << "called " << FormatTimes(min_);
|
||||||
|
} else if (max_ == INT_MAX) {
|
||||||
|
*os << "called at least " << FormatTimes(min_);
|
||||||
|
} else {
|
||||||
|
// 0 < min_ < max_ < INT_MAX
|
||||||
|
*os << "called between " << min_ << " and " << max_ << " times";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Unnamed namespace
|
||||||
|
|
||||||
|
// Describes the given call count to an ostream.
|
||||||
|
void Cardinality::DescribeActualCallCountTo(int actual_call_count,
|
||||||
|
::std::ostream* os) {
|
||||||
|
if (actual_call_count > 0) {
|
||||||
|
*os << "called " << FormatTimes(actual_call_count);
|
||||||
|
} else {
|
||||||
|
*os << "never called";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a cardinality that allows at least n calls.
|
||||||
|
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||||
|
|
||||||
|
// Creates a cardinality that allows at most n calls.
|
||||||
|
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
|
||||||
|
|
||||||
|
// Creates a cardinality that allows any number of calls.
|
||||||
|
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
|
||||||
|
|
||||||
|
// Creates a cardinality that allows between min and max calls.
|
||||||
|
GTEST_API_ Cardinality Between(int min, int max) {
|
||||||
|
return Cardinality(new BetweenCardinalityImpl(min, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a cardinality that allows exactly n calls.
|
||||||
|
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
174
gmock/src/gmock-internal-utils.cc
Normal file
174
gmock/src/gmock-internal-utils.cc
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file defines some utilities useful for implementing Google
|
||||||
|
// Mock. They are subject to change without notice, so please DO NOT
|
||||||
|
// USE THEM IN USER CODE.
|
||||||
|
|
||||||
|
#include "gmock/internal/gmock-internal-utils.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <ostream> // NOLINT
|
||||||
|
#include <string>
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Converts an identifier name to a space-separated list of lower-case
|
||||||
|
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
|
||||||
|
// treated as one word. For example, both "FooBar123" and
|
||||||
|
// "foo_bar_123" are converted to "foo bar 123".
|
||||||
|
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
|
||||||
|
string result;
|
||||||
|
char prev_char = '\0';
|
||||||
|
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
|
||||||
|
// We don't care about the current locale as the input is
|
||||||
|
// guaranteed to be a valid C++ identifier name.
|
||||||
|
const bool starts_new_word = IsUpper(*p) ||
|
||||||
|
(!IsAlpha(prev_char) && IsLower(*p)) ||
|
||||||
|
(!IsDigit(prev_char) && IsDigit(*p));
|
||||||
|
|
||||||
|
if (IsAlNum(*p)) {
|
||||||
|
if (starts_new_word && result != "")
|
||||||
|
result += ' ';
|
||||||
|
result += ToLower(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This class reports Google Mock failures as Google Test failures. A
|
||||||
|
// user can define another class in a similar fashion if he intends to
|
||||||
|
// use Google Mock with a testing framework other than Google Test.
|
||||||
|
class GoogleTestFailureReporter : public FailureReporterInterface {
|
||||||
|
public:
|
||||||
|
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||||
|
const string& message) {
|
||||||
|
AssertHelper(type == kFatal ?
|
||||||
|
TestPartResult::kFatalFailure :
|
||||||
|
TestPartResult::kNonFatalFailure,
|
||||||
|
file,
|
||||||
|
line,
|
||||||
|
message.c_str()) = Message();
|
||||||
|
if (type == kFatal) {
|
||||||
|
posix::Abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns the global failure reporter. Will create a
|
||||||
|
// GoogleTestFailureReporter and return it the first time called.
|
||||||
|
GTEST_API_ FailureReporterInterface* GetFailureReporter() {
|
||||||
|
// Points to the global failure reporter used by Google Mock. gcc
|
||||||
|
// guarantees that the following use of failure_reporter is
|
||||||
|
// thread-safe. We may need to add additional synchronization to
|
||||||
|
// protect failure_reporter if we port Google Mock to other
|
||||||
|
// compilers.
|
||||||
|
static FailureReporterInterface* const failure_reporter =
|
||||||
|
new GoogleTestFailureReporter();
|
||||||
|
return failure_reporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protects global resources (stdout in particular) used by Log().
|
||||||
|
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
|
||||||
|
|
||||||
|
// Returns true iff a log with the given severity is visible according
|
||||||
|
// to the --gmock_verbose flag.
|
||||||
|
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||||
|
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
||||||
|
// Always show the log if --gmock_verbose=info.
|
||||||
|
return true;
|
||||||
|
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
|
||||||
|
// Always hide it if --gmock_verbose=error.
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// If --gmock_verbose is neither "info" nor "error", we treat it
|
||||||
|
// as "warning" (its default value).
|
||||||
|
return severity == kWarning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints the given message to stdout iff 'severity' >= the level
|
||||||
|
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
|
||||||
|
// 0, also prints the stack trace excluding the top
|
||||||
|
// stack_frames_to_skip frames. In opt mode, any positive
|
||||||
|
// stack_frames_to_skip is treated as 0, since we don't know which
|
||||||
|
// function calls will be inlined by the compiler and need to be
|
||||||
|
// conservative.
|
||||||
|
GTEST_API_ void Log(LogSeverity severity,
|
||||||
|
const string& message,
|
||||||
|
int stack_frames_to_skip) {
|
||||||
|
if (!LogIsVisible(severity))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ensures that logs from different threads don't interleave.
|
||||||
|
MutexLock l(&g_log_mutex);
|
||||||
|
|
||||||
|
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
|
||||||
|
// macro.
|
||||||
|
|
||||||
|
if (severity == kWarning) {
|
||||||
|
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||||
|
std::cout << "\nGMOCK WARNING:";
|
||||||
|
}
|
||||||
|
// Pre-pends a new-line to message if it doesn't start with one.
|
||||||
|
if (message.empty() || message[0] != '\n') {
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << message;
|
||||||
|
if (stack_frames_to_skip >= 0) {
|
||||||
|
#ifdef NDEBUG
|
||||||
|
// In opt mode, we have to be conservative and skip no stack frame.
|
||||||
|
const int actual_to_skip = 0;
|
||||||
|
#else
|
||||||
|
// In dbg mode, we can do what the caller tell us to do (plus one
|
||||||
|
// for skipping this function's stack frame).
|
||||||
|
const int actual_to_skip = stack_frames_to_skip + 1;
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
|
// Appends a new-line to message if it doesn't end with one.
|
||||||
|
if (!message.empty() && *message.rbegin() != '\n') {
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << "Stack trace:\n"
|
||||||
|
<< ::testing::internal::GetCurrentOsStackTraceExceptTop(
|
||||||
|
::testing::UnitTest::GetInstance(), actual_to_skip);
|
||||||
|
}
|
||||||
|
std::cout << ::std::flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
498
gmock/src/gmock-matchers.cc
Normal file
498
gmock/src/gmock-matchers.cc
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements Matcher<const string&>, Matcher<string>, and
|
||||||
|
// utilities for defining matchers.
|
||||||
|
|
||||||
|
#include "gmock/gmock-matchers.h"
|
||||||
|
#include "gmock/gmock-generated-matchers.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const string& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const internal::string&>::Matcher(const internal::string& s) {
|
||||||
|
*this = Eq(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const string& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const internal::string&>::Matcher(const char* s) {
|
||||||
|
*this = Eq(internal::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a string whose value is equal to s.
|
||||||
|
Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a string whose value is equal to s.
|
||||||
|
Matcher<internal::string>::Matcher(const char* s) {
|
||||||
|
*this = Eq(internal::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GTEST_HAS_STRING_PIECE_
|
||||||
|
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const StringPiece&>::Matcher(const internal::string& s) {
|
||||||
|
*this = Eq(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const StringPiece&>::Matcher(const char* s) {
|
||||||
|
*this = Eq(internal::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||||
|
// equal to s.
|
||||||
|
Matcher<const StringPiece&>::Matcher(StringPiece s) {
|
||||||
|
*this = Eq(s.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||||
|
Matcher<StringPiece>::Matcher(const internal::string& s) {
|
||||||
|
*this = Eq(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||||
|
Matcher<StringPiece>::Matcher(const char* s) {
|
||||||
|
*this = Eq(internal::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||||
|
Matcher<StringPiece>::Matcher(StringPiece s) {
|
||||||
|
*this = Eq(s.ToString());
|
||||||
|
}
|
||||||
|
#endif // GTEST_HAS_STRING_PIECE_
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||||
|
// the joined string.
|
||||||
|
GTEST_API_ string JoinAsTuple(const Strings& fields) {
|
||||||
|
switch (fields.size()) {
|
||||||
|
case 0:
|
||||||
|
return "";
|
||||||
|
case 1:
|
||||||
|
return fields[0];
|
||||||
|
default:
|
||||||
|
string result = "(" + fields[0];
|
||||||
|
for (size_t i = 1; i < fields.size(); i++) {
|
||||||
|
result += ", ";
|
||||||
|
result += fields[i];
|
||||||
|
}
|
||||||
|
result += ")";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the description for a matcher defined using the MATCHER*()
|
||||||
|
// macro where the user-supplied description string is "", if
|
||||||
|
// 'negation' is false; otherwise returns the description of the
|
||||||
|
// negation of the matcher. 'param_values' contains a list of strings
|
||||||
|
// that are the print-out of the matcher's parameters.
|
||||||
|
GTEST_API_ string FormatMatcherDescription(bool negation,
|
||||||
|
const char* matcher_name,
|
||||||
|
const Strings& param_values) {
|
||||||
|
string result = ConvertIdentifierNameToWords(matcher_name);
|
||||||
|
if (param_values.size() >= 1)
|
||||||
|
result += " " + JoinAsTuple(param_values);
|
||||||
|
return negation ? "not (" + result + ")" : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindMaxBipartiteMatching and its helper class.
|
||||||
|
//
|
||||||
|
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
|
||||||
|
// bipartite matching. Flow is considered to be from left to right.
|
||||||
|
// There is an implicit source node that is connected to all of the left
|
||||||
|
// nodes, and an implicit sink node that is connected to all of the
|
||||||
|
// right nodes. All edges have unit capacity.
|
||||||
|
//
|
||||||
|
// Neither the flow graph nor the residual flow graph are represented
|
||||||
|
// explicitly. Instead, they are implied by the information in 'graph' and
|
||||||
|
// a vector<int> called 'left_' whose elements are initialized to the
|
||||||
|
// value kUnused. This represents the initial state of the algorithm,
|
||||||
|
// where the flow graph is empty, and the residual flow graph has the
|
||||||
|
// following edges:
|
||||||
|
// - An edge from source to each left_ node
|
||||||
|
// - An edge from each right_ node to sink
|
||||||
|
// - An edge from each left_ node to each right_ node, if the
|
||||||
|
// corresponding edge exists in 'graph'.
|
||||||
|
//
|
||||||
|
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
|
||||||
|
// nodes l and r. This induces the following changes:
|
||||||
|
// - The edges (source, l), (l, r), and (r, sink) are added to the
|
||||||
|
// flow graph.
|
||||||
|
// - The same three edges are removed from the residual flow graph.
|
||||||
|
// - The reverse edges (l, source), (r, l), and (sink, r) are added
|
||||||
|
// to the residual flow graph, which is a directional graph
|
||||||
|
// representing unused flow capacity.
|
||||||
|
//
|
||||||
|
// When the method augments a flow (moving left_[l] from some r1 to some
|
||||||
|
// other r2), this can be thought of as "undoing" the above steps with
|
||||||
|
// respect to r1 and "redoing" them with respect to r2.
|
||||||
|
//
|
||||||
|
// It bears repeating that the flow graph and residual flow graph are
|
||||||
|
// never represented explicitly, but can be derived by looking at the
|
||||||
|
// information in 'graph' and in left_.
|
||||||
|
//
|
||||||
|
// As an optimization, there is a second vector<int> called right_ which
|
||||||
|
// does not provide any new information. Instead, it enables more
|
||||||
|
// efficient queries about edges entering or leaving the right-side nodes
|
||||||
|
// of the flow or residual flow graphs. The following invariants are
|
||||||
|
// maintained:
|
||||||
|
//
|
||||||
|
// left[l] == kUnused or right[left[l]] == l
|
||||||
|
// right[r] == kUnused or left[right[r]] == r
|
||||||
|
//
|
||||||
|
// . [ source ] .
|
||||||
|
// . ||| .
|
||||||
|
// . ||| .
|
||||||
|
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
|
||||||
|
// . || | | .
|
||||||
|
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
|
||||||
|
// . | || .
|
||||||
|
// . \----> left[2]=2 ------> right[2]=2 --\|| .
|
||||||
|
// . ||| .
|
||||||
|
// . elements matchers vvv .
|
||||||
|
// . [ sink ] .
|
||||||
|
//
|
||||||
|
// See Also:
|
||||||
|
// [1] Cormen, et al (2001). "Section 26.2: The Ford–Fulkerson method".
|
||||||
|
// "Introduction to Algorithms (Second ed.)", pp. 651–664.
|
||||||
|
// [2] "Ford–Fulkerson algorithm", Wikipedia,
|
||||||
|
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||||
|
class MaxBipartiteMatchState {
|
||||||
|
public:
|
||||||
|
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||||
|
: graph_(&graph),
|
||||||
|
left_(graph_->LhsSize(), kUnused),
|
||||||
|
right_(graph_->RhsSize(), kUnused) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the edges of a maximal match, each in the form {left, right}.
|
||||||
|
ElementMatcherPairs Compute() {
|
||||||
|
// 'seen' is used for path finding { 0: unseen, 1: seen }.
|
||||||
|
::std::vector<char> seen;
|
||||||
|
// Searches the residual flow graph for a path from each left node to
|
||||||
|
// the sink in the residual flow graph, and if one is found, add flow
|
||||||
|
// to the graph. It's okay to search through the left nodes once. The
|
||||||
|
// edge from the implicit source node to each previously-visited left
|
||||||
|
// node will have flow if that left node has any path to the sink
|
||||||
|
// whatsoever. Subsequent augmentations can only add flow to the
|
||||||
|
// network, and cannot take away that previous flow unit from the source.
|
||||||
|
// Since the source-to-left edge can only carry one flow unit (or,
|
||||||
|
// each element can be matched to only one matcher), there is no need
|
||||||
|
// to visit the left nodes more than once looking for augmented paths.
|
||||||
|
// The flow is known to be possible or impossible by looking at the
|
||||||
|
// node once.
|
||||||
|
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
|
||||||
|
// Reset the path-marking vector and try to find a path from
|
||||||
|
// source to sink starting at the left_[ilhs] node.
|
||||||
|
GTEST_CHECK_(left_[ilhs] == kUnused)
|
||||||
|
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
|
||||||
|
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
|
||||||
|
seen.assign(graph_->RhsSize(), 0);
|
||||||
|
TryAugment(ilhs, &seen);
|
||||||
|
}
|
||||||
|
ElementMatcherPairs result;
|
||||||
|
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
|
||||||
|
size_t irhs = left_[ilhs];
|
||||||
|
if (irhs == kUnused) continue;
|
||||||
|
result.push_back(ElementMatcherPair(ilhs, irhs));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const size_t kUnused = static_cast<size_t>(-1);
|
||||||
|
|
||||||
|
// Perform a depth-first search from left node ilhs to the sink. If a
|
||||||
|
// path is found, flow is added to the network by linking the left and
|
||||||
|
// right vector elements corresponding each segment of the path.
|
||||||
|
// Returns true if a path to sink was found, which means that a unit of
|
||||||
|
// flow was added to the network. The 'seen' vector elements correspond
|
||||||
|
// to right nodes and are marked to eliminate cycles from the search.
|
||||||
|
//
|
||||||
|
// Left nodes will only be explored at most once because they
|
||||||
|
// are accessible from at most one right node in the residual flow
|
||||||
|
// graph.
|
||||||
|
//
|
||||||
|
// Note that left_[ilhs] is the only element of left_ that TryAugment will
|
||||||
|
// potentially transition from kUnused to another value. Any other
|
||||||
|
// left_ element holding kUnused before TryAugment will be holding it
|
||||||
|
// when TryAugment returns.
|
||||||
|
//
|
||||||
|
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
||||||
|
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
||||||
|
if ((*seen)[irhs])
|
||||||
|
continue;
|
||||||
|
if (!graph_->HasEdge(ilhs, irhs))
|
||||||
|
continue;
|
||||||
|
// There's an available edge from ilhs to irhs.
|
||||||
|
(*seen)[irhs] = 1;
|
||||||
|
// Next a search is performed to determine whether
|
||||||
|
// this edge is a dead end or leads to the sink.
|
||||||
|
//
|
||||||
|
// right_[irhs] == kUnused means that there is residual flow from
|
||||||
|
// right node irhs to the sink, so we can use that to finish this
|
||||||
|
// flow path and return success.
|
||||||
|
//
|
||||||
|
// Otherwise there is residual flow to some ilhs. We push flow
|
||||||
|
// along that path and call ourselves recursively to see if this
|
||||||
|
// ultimately leads to sink.
|
||||||
|
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
|
||||||
|
// Add flow from left_[ilhs] to right_[irhs].
|
||||||
|
left_[ilhs] = irhs;
|
||||||
|
right_[irhs] = ilhs;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MatchMatrix* graph_; // not owned
|
||||||
|
// Each element of the left_ vector represents a left hand side node
|
||||||
|
// (i.e. an element) and each element of right_ is a right hand side
|
||||||
|
// node (i.e. a matcher). The values in the left_ vector indicate
|
||||||
|
// outflow from that node to a node on the the right_ side. The values
|
||||||
|
// in the right_ indicate inflow, and specify which left_ node is
|
||||||
|
// feeding that right_ node, if any. For example, left_[3] == 1 means
|
||||||
|
// there's a flow from element #3 to matcher #1. Such a flow would also
|
||||||
|
// be redundantly represented in the right_ vector as right_[1] == 3.
|
||||||
|
// Elements of left_ and right_ are either kUnused or mutually
|
||||||
|
// referent. Mutually referent means that left_[right_[i]] = i and
|
||||||
|
// right_[left_[i]] = i.
|
||||||
|
::std::vector<size_t> left_;
|
||||||
|
::std::vector<size_t> right_;
|
||||||
|
|
||||||
|
GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState);
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t MaxBipartiteMatchState::kUnused;
|
||||||
|
|
||||||
|
GTEST_API_ ElementMatcherPairs
|
||||||
|
FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||||
|
return MaxBipartiteMatchState(g).Compute();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||||
|
::std::ostream* stream) {
|
||||||
|
typedef ElementMatcherPairs::const_iterator Iter;
|
||||||
|
::std::ostream& os = *stream;
|
||||||
|
os << "{";
|
||||||
|
const char *sep = "";
|
||||||
|
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||||
|
os << sep << "\n ("
|
||||||
|
<< "element #" << it->first << ", "
|
||||||
|
<< "matcher #" << it->second << ")";
|
||||||
|
sep = ",";
|
||||||
|
}
|
||||||
|
os << "\n}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tries to find a pairing, and explains the result.
|
||||||
|
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
|
||||||
|
MatchResultListener* listener) {
|
||||||
|
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
|
||||||
|
|
||||||
|
size_t max_flow = matches.size();
|
||||||
|
bool result = (max_flow == matrix.RhsSize());
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
if (listener->IsInterested()) {
|
||||||
|
*listener << "where no permutation of the elements can "
|
||||||
|
"satisfy all matchers, and the closest match is "
|
||||||
|
<< max_flow << " of " << matrix.RhsSize()
|
||||||
|
<< " matchers with the pairings:\n";
|
||||||
|
LogElementMatcherPairVec(matches, listener->stream());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches.size() > 1) {
|
||||||
|
if (listener->IsInterested()) {
|
||||||
|
const char *sep = "where:\n";
|
||||||
|
for (size_t mi = 0; mi < matches.size(); ++mi) {
|
||||||
|
*listener << sep << " - element #" << matches[mi].first
|
||||||
|
<< " is matched by matcher #" << matches[mi].second;
|
||||||
|
sep = ",\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MatchMatrix::NextGraph() {
|
||||||
|
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||||
|
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||||
|
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||||
|
if (!b) {
|
||||||
|
b = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchMatrix::Randomize() {
|
||||||
|
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||||
|
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||||
|
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||||
|
b = static_cast<char>(rand() & 1); // NOLINT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string MatchMatrix::DebugString() const {
|
||||||
|
::std::stringstream ss;
|
||||||
|
const char *sep = "";
|
||||||
|
for (size_t i = 0; i < LhsSize(); ++i) {
|
||||||
|
ss << sep;
|
||||||
|
for (size_t j = 0; j < RhsSize(); ++j) {
|
||||||
|
ss << HasEdge(i, j);
|
||||||
|
}
|
||||||
|
sep = ";";
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
||||||
|
::std::ostream* os) const {
|
||||||
|
if (matcher_describers_.empty()) {
|
||||||
|
*os << "is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (matcher_describers_.size() == 1) {
|
||||||
|
*os << "has " << Elements(1) << " and that element ";
|
||||||
|
matcher_describers_[0]->DescribeTo(os);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*os << "has " << Elements(matcher_describers_.size())
|
||||||
|
<< " and there exists some permutation of elements such that:\n";
|
||||||
|
const char* sep = "";
|
||||||
|
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||||
|
*os << sep << " - element #" << i << " ";
|
||||||
|
matcher_describers_[i]->DescribeTo(os);
|
||||||
|
sep = ", and\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||||
|
::std::ostream* os) const {
|
||||||
|
if (matcher_describers_.empty()) {
|
||||||
|
*os << "isn't empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (matcher_describers_.size() == 1) {
|
||||||
|
*os << "doesn't have " << Elements(1)
|
||||||
|
<< ", or has " << Elements(1) << " that ";
|
||||||
|
matcher_describers_[0]->DescribeNegationTo(os);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*os << "doesn't have " << Elements(matcher_describers_.size())
|
||||||
|
<< ", or there exists no permutation of elements such that:\n";
|
||||||
|
const char* sep = "";
|
||||||
|
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||||
|
*os << sep << " - element #" << i << " ";
|
||||||
|
matcher_describers_[i]->DescribeTo(os);
|
||||||
|
sep = ", and\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks that all matchers match at least one element, and that all
|
||||||
|
// elements match at least one matcher. This enables faster matching
|
||||||
|
// and better error reporting.
|
||||||
|
// Returns false, writing an explanation to 'listener', if and only
|
||||||
|
// if the success criteria are not met.
|
||||||
|
bool UnorderedElementsAreMatcherImplBase::
|
||||||
|
VerifyAllElementsAndMatchersAreMatched(
|
||||||
|
const ::std::vector<string>& element_printouts,
|
||||||
|
const MatchMatrix& matrix,
|
||||||
|
MatchResultListener* listener) const {
|
||||||
|
bool result = true;
|
||||||
|
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||||
|
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||||
|
|
||||||
|
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
|
||||||
|
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
|
||||||
|
char matched = matrix.HasEdge(ilhs, irhs);
|
||||||
|
element_matched[ilhs] |= matched;
|
||||||
|
matcher_matched[irhs] |= matched;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char* sep =
|
||||||
|
"where the following matchers don't match any elements:\n";
|
||||||
|
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
||||||
|
if (matcher_matched[mi])
|
||||||
|
continue;
|
||||||
|
result = false;
|
||||||
|
if (listener->IsInterested()) {
|
||||||
|
*listener << sep << "matcher #" << mi << ": ";
|
||||||
|
matcher_describers_[mi]->DescribeTo(listener->stream());
|
||||||
|
sep = ",\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char* sep =
|
||||||
|
"where the following elements don't match any matchers:\n";
|
||||||
|
const char* outer_sep = "";
|
||||||
|
if (!result) {
|
||||||
|
outer_sep = "\nand ";
|
||||||
|
}
|
||||||
|
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
||||||
|
if (element_matched[ei])
|
||||||
|
continue;
|
||||||
|
result = false;
|
||||||
|
if (listener->IsInterested()) {
|
||||||
|
*listener << outer_sep << sep << "element #" << ei << ": "
|
||||||
|
<< element_printouts[ei];
|
||||||
|
sep = ",\n";
|
||||||
|
outer_sep = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
813
gmock/src/gmock-spec-builders.cc
Normal file
813
gmock/src/gmock-spec-builders.cc
Normal file
@@ -0,0 +1,813 @@
|
|||||||
|
// Copyright 2007, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
// Google Mock - a framework for writing C++ mock classes.
|
||||||
|
//
|
||||||
|
// This file implements the spec builder syntax (ON_CALL and
|
||||||
|
// EXPECT_CALL).
|
||||||
|
|
||||||
|
#include "gmock/gmock-spec-builders.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream> // NOLINT
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||||
|
# include <unistd.h> // NOLINT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Protects the mock object registry (in class Mock), all function
|
||||||
|
// mockers, and all expectations.
|
||||||
|
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
|
||||||
|
|
||||||
|
// Logs a message including file and line number information.
|
||||||
|
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
|
||||||
|
const char* file, int line,
|
||||||
|
const string& message) {
|
||||||
|
::std::ostringstream s;
|
||||||
|
s << file << ":" << line << ": " << message << ::std::endl;
|
||||||
|
Log(severity, s.str(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructs an ExpectationBase object.
|
||||||
|
ExpectationBase::ExpectationBase(const char* a_file,
|
||||||
|
int a_line,
|
||||||
|
const string& a_source_text)
|
||||||
|
: file_(a_file),
|
||||||
|
line_(a_line),
|
||||||
|
source_text_(a_source_text),
|
||||||
|
cardinality_specified_(false),
|
||||||
|
cardinality_(Exactly(1)),
|
||||||
|
call_count_(0),
|
||||||
|
retired_(false),
|
||||||
|
extra_matcher_specified_(false),
|
||||||
|
repeated_action_specified_(false),
|
||||||
|
retires_on_saturation_(false),
|
||||||
|
last_clause_(kNone),
|
||||||
|
action_count_checked_(false) {}
|
||||||
|
|
||||||
|
// Destructs an ExpectationBase object.
|
||||||
|
ExpectationBase::~ExpectationBase() {}
|
||||||
|
|
||||||
|
// Explicitly specifies the cardinality of this expectation. Used by
|
||||||
|
// the subclasses to implement the .Times() clause.
|
||||||
|
void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
|
||||||
|
cardinality_specified_ = true;
|
||||||
|
cardinality_ = a_cardinality;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retires all pre-requisites of this expectation.
|
||||||
|
void ExpectationBase::RetireAllPreRequisites()
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
|
if (is_retired()) {
|
||||||
|
// We can take this short-cut as we never retire an expectation
|
||||||
|
// until we have retired all its pre-requisites.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||||
|
it != immediate_prerequisites_.end(); ++it) {
|
||||||
|
ExpectationBase* const prerequisite = it->expectation_base().get();
|
||||||
|
if (!prerequisite->is_retired()) {
|
||||||
|
prerequisite->RetireAllPreRequisites();
|
||||||
|
prerequisite->Retire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true iff all pre-requisites of this expectation have been
|
||||||
|
// satisfied.
|
||||||
|
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
|
g_gmock_mutex.AssertHeld();
|
||||||
|
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||||
|
it != immediate_prerequisites_.end(); ++it) {
|
||||||
|
if (!(it->expectation_base()->IsSatisfied()) ||
|
||||||
|
!(it->expectation_base()->AllPrerequisitesAreSatisfied()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds unsatisfied pre-requisites of this expectation to 'result'.
|
||||||
|
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
|
g_gmock_mutex.AssertHeld();
|
||||||
|
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||||
|
it != immediate_prerequisites_.end(); ++it) {
|
||||||
|
if (it->expectation_base()->IsSatisfied()) {
|
||||||
|
// If *it is satisfied and has a call count of 0, some of its
|
||||||
|
// pre-requisites may not be satisfied yet.
|
||||||
|
if (it->expectation_base()->call_count_ == 0) {
|
||||||
|
it->expectation_base()->FindUnsatisfiedPrerequisites(result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Now that we know *it is unsatisfied, we are not so interested
|
||||||
|
// in whether its pre-requisites are satisfied. Therefore we
|
||||||
|
// don't recursively call FindUnsatisfiedPrerequisites() here.
|
||||||
|
*result += *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describes how many times a function call matching this
|
||||||
|
// expectation has occurred.
|
||||||
|
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
|
g_gmock_mutex.AssertHeld();
|
||||||
|
|
||||||
|
// Describes how many times the function is expected to be called.
|
||||||
|
*os << " Expected: to be ";
|
||||||
|
cardinality().DescribeTo(os);
|
||||||
|
*os << "\n Actual: ";
|
||||||
|
Cardinality::DescribeActualCallCountTo(call_count(), os);
|
||||||
|
|
||||||
|
// Describes the state of the expectation (e.g. is it satisfied?
|
||||||
|
// is it active?).
|
||||||
|
*os << " - " << (IsOverSaturated() ? "over-saturated" :
|
||||||
|
IsSaturated() ? "saturated" :
|
||||||
|
IsSatisfied() ? "satisfied" : "unsatisfied")
|
||||||
|
<< " and "
|
||||||
|
<< (is_retired() ? "retired" : "active");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks the action count (i.e. the number of WillOnce() and
|
||||||
|
// WillRepeatedly() clauses) against the cardinality if this hasn't
|
||||||
|
// been done before. Prints a warning if there are too many or too
|
||||||
|
// few actions.
|
||||||
|
void ExpectationBase::CheckActionCountIfNotDone() const
|
||||||
|
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||||
|
bool should_check = false;
|
||||||
|
{
|
||||||
|
MutexLock l(&mutex_);
|
||||||
|
if (!action_count_checked_) {
|
||||||
|
action_count_checked_ = true;
|
||||||
|
should_check = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (should_check) {
|
||||||
|
if (!cardinality_specified_) {
|
||||||
|
// The cardinality was inferred - no need to check the action
|
||||||
|
// count against it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The cardinality was explicitly specified.
|
||||||
|
const int action_count = static_cast<int>(untyped_actions_.size());
|
||||||
|
const int upper_bound = cardinality().ConservativeUpperBound();
|
||||||
|
const int lower_bound = cardinality().ConservativeLowerBound();
|
||||||
|
bool too_many; // True if there are too many actions, or false
|
||||||
|
// if there are too few.
|
||||||
|
if (action_count > upper_bound ||
|
||||||
|
(action_count == upper_bound && repeated_action_specified_)) {
|
||||||
|
too_many = true;
|
||||||
|
} else if (0 < action_count && action_count < lower_bound &&
|
||||||
|
!repeated_action_specified_) {
|
||||||
|
too_many = false;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
::std::stringstream ss;
|
||||||
|
DescribeLocationTo(&ss);
|
||||||
|
ss << "Too " << (too_many ? "many" : "few")
|
||||||
|
<< " actions specified in " << source_text() << "...\n"
|
||||||
|
<< "Expected to be ";
|
||||||
|
cardinality().DescribeTo(&ss);
|
||||||
|
ss << ", but has " << (too_many ? "" : "only ")
|
||||||
|
<< action_count << " WillOnce()"
|
||||||
|
<< (action_count == 1 ? "" : "s");
|
||||||
|
if (repeated_action_specified_) {
|
||||||
|
ss << " and a WillRepeatedly()";
|
||||||
|
}
|
||||||
|
ss << ".";
|
||||||
|
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the .Times() clause.
|
||||||
|
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
|
||||||
|
if (last_clause_ == kTimes) {
|
||||||
|
ExpectSpecProperty(false,
|
||||||
|
".Times() cannot appear "
|
||||||
|
"more than once in an EXPECT_CALL().");
|
||||||
|
} else {
|
||||||
|
ExpectSpecProperty(last_clause_ < kTimes,
|
||||||
|
".Times() cannot appear after "
|
||||||
|
".InSequence(), .WillOnce(), .WillRepeatedly(), "
|
||||||
|
"or .RetiresOnSaturation().");
|
||||||
|
}
|
||||||
|
last_clause_ = kTimes;
|
||||||
|
|
||||||
|
SpecifyCardinality(a_cardinality);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Points to the implicit sequence introduced by a living InSequence
|
||||||
|
// object (if any) in the current thread or NULL.
|
||||||
|
GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||||
|
|
||||||
|
// Reports an uninteresting call (whose description is in msg) in the
|
||||||
|
// manner specified by 'reaction'.
|
||||||
|
void ReportUninterestingCall(CallReaction reaction, const string& msg) {
|
||||||
|
switch (reaction) {
|
||||||
|
case kAllow:
|
||||||
|
Log(kInfo, msg, 3);
|
||||||
|
break;
|
||||||
|
case kWarn:
|
||||||
|
Log(kWarning, msg, 3);
|
||||||
|
break;
|
||||||
|
default: // FAIL
|
||||||
|
Expect(false, NULL, -1, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
|
||||||
|
: mock_obj_(NULL), name_("") {}
|
||||||
|
|
||||||
|
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
||||||
|
|
||||||
|
// Sets the mock object this mock method belongs to, and registers
|
||||||
|
// this information in the global mock registry. Will be called
|
||||||
|
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
|
||||||
|
// method.
|
||||||
|
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
|
{
|
||||||
|
MutexLock l(&g_gmock_mutex);
|
||||||
|
mock_obj_ = mock_obj;
|
||||||
|
}
|
||||||
|
Mock::Register(mock_obj, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the mock object this mock method belongs to, and sets the name
|
||||||
|
// of the mock function. Will be called upon each invocation of this
|
||||||
|
// mock function.
|
||||||
|
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
||||||
|
const char* name)
|
||||||
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
|
// We protect name_ under g_gmock_mutex in case this mock function
|
||||||
|
// is called from two threads concurrently.
|
||||||
|
MutexLock l(&g_gmock_mutex);
|
||||||
|
mock_obj_ = mock_obj;
|
||||||
|
name_ = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the name of the function being mocked. Must be called
|
||||||
|
// after RegisterOwner() or SetOwnerAndName() has been called.
|
||||||
|
const void* UntypedFunctionMockerBase::MockObject() const
|
||||||
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
|
const void* mock_obj;
|
||||||
|
{
|
||||||
|
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||||
|
// function is called from two threads concurrently.
|
||||||
|
MutexLock l(&g_gmock_mutex);
|
||||||
|
Assert(mock_obj_ != NULL, __FILE__, __LINE__,
|
||||||
|
"MockObject() must not be called before RegisterOwner() or "
|
||||||
|
"SetOwnerAndName() has been called.");
|
||||||
|
mock_obj = mock_obj_;
|
||||||
|
}
|
||||||
|
return mock_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the name of this mock method. Must be called after
|
||||||
|
// SetOwnerAndName() has been called.
|
||||||
|
const char* UntypedFunctionMockerBase::Name() const
|
||||||
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
|
const char* name;
|
||||||
|
{
|
||||||
|
// We protect name_ under g_gmock_mutex in case this mock
|
||||||
|
// function is called from two threads concurrently.
|
||||||
|
MutexLock l(&g_gmock_mutex);
|
||||||
|
Assert(name_ != NULL, __FILE__, __LINE__,
|
||||||
|
"Name() must not be called before SetOwnerAndName() has "
|
||||||
|
"been called.");
|
||||||
|
name = name_;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculates the result of invoking this mock function with the given
|
||||||
|
// arguments, prints it, and returns it. The caller is responsible
|
||||||
|
// for deleting the result.
|
||||||
|
const UntypedActionResultHolderBase*
|
||||||
|
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
|
||||||
|
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||||
|
if (untyped_expectations_.size() == 0) {
|
||||||
|
// No expectation is set on this mock method - we have an
|
||||||
|
// uninteresting call.
|
||||||
|
|
||||||
|
// We must get Google Mock's reaction on uninteresting calls
|
||||||
|
// made on this mock object BEFORE performing the action,
|
||||||
|
// because the action may DELETE the mock object and make the
|
||||||
|
// following expression meaningless.
|
||||||
|
const CallReaction reaction =
|
||||||
|
Mock::GetReactionOnUninterestingCalls(MockObject());
|
||||||
|
|
||||||
|
// True iff we need to print this call's arguments and return
|
||||||
|
// value. This definition must be kept in sync with
|
||||||
|
// the behavior of ReportUninterestingCall().
|
||||||
|
const bool need_to_report_uninteresting_call =
|
||||||
|
// If the user allows this uninteresting call, we print it
|
||||||
|
// only when he wants informational messages.
|
||||||
|
reaction == kAllow ? LogIsVisible(kInfo) :
|
||||||
|
// If the user wants this to be a warning, we print it only
|
||||||
|
// when he wants to see warnings.
|
||||||
|
reaction == kWarn ? LogIsVisible(kWarning) :
|
||||||
|
// Otherwise, the user wants this to be an error, and we
|
||||||
|
// should always print detailed information in the error.
|
||||||
|
true;
|
||||||
|
|
||||||
|
if (!need_to_report_uninteresting_call) {
|
||||||
|
// Perform the action without printing the call information.
|
||||||
|
return this->UntypedPerformDefaultAction(untyped_args, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warns about the uninteresting call.
|
||||||
|
::std::stringstream ss;
|
||||||
|
this->UntypedDescribeUninterestingCall(untyped_args, &ss);
|
||||||
|
|
||||||
|
// Calculates the function result.
|
||||||
|
const UntypedActionResultHolderBase* const result =
|
||||||
|
this->UntypedPerformDefaultAction(untyped_args, ss.str());
|
||||||
|
|
||||||
|
// Prints the function result.
|
||||||
|
if (result != NULL)
|
||||||
|
result->PrintAsActionResult(&ss);
|
||||||
|
|
||||||
|
ReportUninterestingCall(reaction, ss.str());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_excessive = false;
|
||||||
|
::std::stringstream ss;
|
||||||
|
::std::stringstream why;
|
||||||
|
::std::stringstream loc;
|
||||||
|
const void* untyped_action = NULL;
|
||||||
|
|
||||||
|
// The UntypedFindMatchingExpectation() function acquires and
|
||||||
|
// releases g_gmock_mutex.
|
||||||
|
const ExpectationBase* const untyped_expectation =
|
||||||
|
this->UntypedFindMatchingExpectation(
|
||||||
|
untyped_args, &untyped_action, &is_excessive,
|
||||||
|
&ss, &why);
|
||||||
|
const bool found = untyped_expectation != NULL;
|
||||||
|
|
||||||
|
// True iff we need to print the call's arguments and return value.
|
||||||
|
// This definition must be kept in sync with the uses of Expect()
|
||||||
|
// and Log() in this function.
|
||||||
|
const bool need_to_report_call =
|
||||||
|
!found || is_excessive || LogIsVisible(kInfo);
|
||||||
|
if (!need_to_report_call) {
|
||||||
|
// Perform the action without printing the call information.
|
||||||
|
return
|
||||||
|
untyped_action == NULL ?
|
||||||
|
this->UntypedPerformDefaultAction(untyped_args, "") :
|
||||||
|
this->UntypedPerformAction(untyped_action, untyped_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << " Function call: " << Name();
|
||||||
|
this->UntypedPrintArgs(untyped_args, &ss);
|
||||||
|
|
||||||
|
// In case the action deletes a piece of the expectation, we
|
||||||
|
// generate the message beforehand.
|
||||||
|
if (found && !is_excessive) {
|
||||||
|
untyped_expectation->DescribeLocationTo(&loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const UntypedActionResultHolderBase* const result =
|
||||||
|
untyped_action == NULL ?
|
||||||
|
this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
|
||||||
|
this->UntypedPerformAction(untyped_action, untyped_args);
|
||||||
|
if (result != NULL)
|
||||||
|
result->PrintAsActionResult(&ss);
|
||||||
|
ss << "\n" << why.str();
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
// No expectation matches this call - reports a failure.
|
||||||
|
Expect(false, NULL, -1, ss.str());
|
||||||
|
} else if (is_excessive) {
|
||||||
|
// We had an upper-bound violation and the failure message is in ss.
|
||||||
|
Expect(false, untyped_expectation->file(),
|
||||||
|
untyped_expectation->line(), ss.str());
|
||||||
|
} else {
|
||||||
|
// We had an expected call and the matching expectation is
|
||||||
|
// described in ss.
|
||||||
|
Log(kInfo, loc.str() + ss.str(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns an Expectation object that references and co-owns exp,
|
||||||
|
// which must be an expectation on this mock function.
|
||||||
|
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
|
||||||
|
for (UntypedExpectations::const_iterator it =
|
||||||
|
untyped_expectations_.begin();
|
||||||
|
it != untyped_expectations_.end(); ++it) {
|
||||||
|
if (it->get() == exp) {
|
||||||
|
return Expectation(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(false, __FILE__, __LINE__, "Cannot find expectation.");
|
||||||
|
return Expectation();
|
||||||
|
// The above statement is just to make the code compile, and will
|
||||||
|
// never be executed.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies that all expectations on this mock function have been
|
||||||
|
// satisfied. Reports one or more Google Test non-fatal failures
|
||||||
|
// and returns false if not.
|
||||||
|
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||||
|
g_gmock_mutex.AssertHeld();
|
||||||
|
bool expectations_met = true;
|
||||||
|
for (UntypedExpectations::const_iterator it =
|
||||||
|
untyped_expectations_.begin();
|
||||||
|
it != untyped_expectations_.end(); ++it) {
|
||||||
|
ExpectationBase* const untyped_expectation = it->get();
|
||||||
|
if (untyped_expectation->IsOverSaturated()) {
|
||||||
|
// There was an upper-bound violation. Since the error was
|
||||||
|
// already reported when it occurred, there is no need to do
|
||||||
|
// anything here.
|
||||||
|
expectations_met = false;
|
||||||
|
} else if (!untyped_expectation->IsSatisfied()) {
|
||||||
|
expectations_met = false;
|
||||||
|
::std::stringstream ss;
|
||||||
|
ss << "Actual function call count doesn't match "
|
||||||
|
<< untyped_expectation->source_text() << "...\n";
|
||||||
|
// No need to show the source file location of the expectation
|
||||||
|
// in the description, as the Expect() call that follows already
|
||||||
|
// takes care of it.
|
||||||
|
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss);
|
||||||
|
untyped_expectation->DescribeCallCountTo(&ss);
|
||||||
|
Expect(false, untyped_expectation->file(),
|
||||||
|
untyped_expectation->line(), ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deleting our expectations may trigger other mock objects to be deleted, for
|
||||||
|
// example if an action contains a reference counted smart pointer to that
|
||||||
|
// mock object, and that is the last reference. So if we delete our
|
||||||
|
// expectations within the context of the global mutex we may deadlock when
|
||||||
|
// this method is called again. Instead, make a copy of the set of
|
||||||
|
// expectations to delete, clear our set within the mutex, and then clear the
|
||||||
|
// copied set outside of it.
|
||||||
|
UntypedExpectations expectations_to_delete;
|
||||||
|
untyped_expectations_.swap(expectations_to_delete);
|
||||||
|
|
||||||
|
g_gmock_mutex.Unlock();
|
||||||
|
expectations_to_delete.clear();
|
||||||
|
g_gmock_mutex.Lock();
|
||||||
|
|
||||||
|
return expectations_met;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Class Mock.
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
|
||||||
|
|
||||||
|
// The current state of a mock object. Such information is needed for
|
||||||
|
// detecting leaked mock objects and explicitly verifying a mock's
|
||||||
|
// expectations.
|
||||||
|
struct MockObjectState {
|
||||||
|
MockObjectState()
|
||||||
|
: first_used_file(NULL), first_used_line(-1), leakable(false) {}
|
||||||
|
|
||||||
|
// Where in the source file an ON_CALL or EXPECT_CALL is first
|
||||||
|
// invoked on this mock object.
|
||||||
|
const char* first_used_file;
|
||||||
|
int first_used_line;
|
||||||
|
::std::string first_used_test_case;
|
||||||
|
::std::string first_used_test;
|
||||||
|
bool leakable; // true iff it's OK to leak the object.
|
||||||
|
FunctionMockers function_mockers; // All registered methods of the object.
|
||||||
|
};
|
||||||
|
|
||||||
|
// A global registry holding the state of all mock objects that are
|
||||||
|
// alive. A mock object is added to this registry the first time
|
||||||
|
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It
|
||||||
|
// is removed from the registry in the mock object's destructor.
|
||||||
|
class MockObjectRegistry {
|
||||||
|
public:
|
||||||
|
// Maps a mock object (identified by its address) to its state.
|
||||||
|
typedef std::map<const void*, MockObjectState> StateMap;
|
||||||
|
|
||||||
|
// This destructor will be called when a program exits, after all
|
||||||
|
// tests in it have been run. By then, there should be no mock
|
||||||
|
// object alive. Therefore we report any living object as test
|
||||||
|
// failure, unless the user explicitly asked us to ignore it.
|
||||||
|
~MockObjectRegistry() {
|
||||||
|
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
|
||||||
|
// a macro.
|
||||||
|
|
||||||
|
if (!GMOCK_FLAG(catch_leaked_mocks))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int leaked_count = 0;
|
||||||
|
for (StateMap::const_iterator it = states_.begin(); it != states_.end();
|
||||||
|
++it) {
|
||||||
|
if (it->second.leakable) // The user said it's fine to leak this object.
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// TODO(wan@google.com): Print the type of the leaked object.
|
||||||
|
// This can help the user identify the leaked object.
|
||||||
|
std::cout << "\n";
|
||||||
|
const MockObjectState& state = it->second;
|
||||||
|
std::cout << internal::FormatFileLocation(state.first_used_file,
|
||||||
|
state.first_used_line);
|
||||||
|
std::cout << " ERROR: this mock object";
|
||||||
|
if (state.first_used_test != "") {
|
||||||
|
std::cout << " (used in test " << state.first_used_test_case << "."
|
||||||
|
<< state.first_used_test << ")";
|
||||||
|
}
|
||||||
|
std::cout << " should be deleted but never is. Its address is @"
|
||||||
|
<< it->first << ".";
|
||||||
|
leaked_count++;
|
||||||
|
}
|
||||||
|
if (leaked_count > 0) {
|
||||||
|
std::cout << "\nERROR: " << leaked_count
|
||||||
|
<< " leaked mock " << (leaked_count == 1 ? "object" : "objects")
|
||||||
|
<< " found at program exit.\n";
|
||||||
|
std::cout.flush();
|
||||||
|
::std::cerr.flush();
|
||||||
|
// RUN_ALL_TESTS() has already returned when this destructor is
|
||||||
|
// called. Therefore we cannot use the normal Google Test
|
||||||
|
// failure reporting mechanism.
|
||||||
|
_exit(1); // We cannot call exit() as it is not reentrant and
|
||||||
|
// may already have been called.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateMap& states() { return states_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
StateMap states_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Protected by g_gmock_mutex.
|
||||||
|
MockObjectRegistry g_mock_object_registry;
|
||||||
|
|
||||||
|
// Maps a mock object to the reaction Google Mock should have when an
|
||||||
|
// uninteresting method is called. Protected by g_gmock_mutex.
|
||||||
|
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
|
||||||
|
|
||||||
|
// Sets the reaction Google Mock should have when an uninteresting
|
||||||
|
// method of the given mock object is called.
|
||||||
|
void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||||
|
internal::CallReaction reaction)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
g_uninteresting_call_reaction[mock_obj] = reaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Tells Google Mock to allow uninteresting calls on the given mock
|
||||||
|
// object.
|
||||||
|
void Mock::AllowUninterestingCalls(const void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tells Google Mock to warn the user about uninteresting calls on the
|
||||||
|
// given mock object.
|
||||||
|
void Mock::WarnUninterestingCalls(const void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tells Google Mock to fail uninteresting calls on the given mock
|
||||||
|
// object.
|
||||||
|
void Mock::FailUninterestingCalls(const void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tells Google Mock the given mock object is being destroyed and its
|
||||||
|
// entry in the call-reaction table should be removed.
|
||||||
|
void Mock::UnregisterCallReaction(const void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
g_uninteresting_call_reaction.erase(mock_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the reaction Google Mock will have on uninteresting calls
|
||||||
|
// made on the given mock object.
|
||||||
|
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||||
|
const void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||||
|
internal::kDefault : g_uninteresting_call_reaction[mock_obj];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||||
|
// objects.
|
||||||
|
void Mock::AllowLeak(const void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies and clears all expectations on the given mock object. If
|
||||||
|
// the expectations aren't satisfied, generates one or more Google
|
||||||
|
// Test non-fatal failures and returns false.
|
||||||
|
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies all expectations on the given mock object and clears its
|
||||||
|
// default actions and expectations. Returns true iff the
|
||||||
|
// verification was successful.
|
||||||
|
bool Mock::VerifyAndClear(void* mock_obj)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
ClearDefaultActionsLocked(mock_obj);
|
||||||
|
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies and clears all expectations on the given mock object. If
|
||||||
|
// the expectations aren't satisfied, generates one or more Google
|
||||||
|
// Test non-fatal failures and returns false.
|
||||||
|
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||||
|
internal::g_gmock_mutex.AssertHeld();
|
||||||
|
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||||
|
// No EXPECT_CALL() was set on the given mock object.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies and clears the expectations on each mock method in the
|
||||||
|
// given mock object.
|
||||||
|
bool expectations_met = true;
|
||||||
|
FunctionMockers& mockers =
|
||||||
|
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||||
|
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||||
|
it != mockers.end(); ++it) {
|
||||||
|
if (!(*it)->VerifyAndClearExpectationsLocked()) {
|
||||||
|
expectations_met = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't clear the content of mockers, as they may still be
|
||||||
|
// needed by ClearDefaultActionsLocked().
|
||||||
|
return expectations_met;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registers a mock object and a mock method it owns.
|
||||||
|
void Mock::Register(const void* mock_obj,
|
||||||
|
internal::UntypedFunctionMockerBase* mocker)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tells Google Mock where in the source code mock_obj is used in an
|
||||||
|
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
|
||||||
|
// information helps the user identify which object it is.
|
||||||
|
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||||
|
const char* file, int line)
|
||||||
|
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||||
|
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||||
|
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||||
|
if (state.first_used_file == NULL) {
|
||||||
|
state.first_used_file = file;
|
||||||
|
state.first_used_line = line;
|
||||||
|
const TestInfo* const test_info =
|
||||||
|
UnitTest::GetInstance()->current_test_info();
|
||||||
|
if (test_info != NULL) {
|
||||||
|
// TODO(wan@google.com): record the test case name when the
|
||||||
|
// ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
|
||||||
|
// TearDownTestCase().
|
||||||
|
state.first_used_test_case = test_info->test_case_name();
|
||||||
|
state.first_used_test = test_info->name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregisters a mock method; removes the owning mock object from the
|
||||||
|
// registry when the last mock method associated with it has been
|
||||||
|
// unregistered. This is called only in the destructor of
|
||||||
|
// FunctionMockerBase.
|
||||||
|
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||||
|
internal::g_gmock_mutex.AssertHeld();
|
||||||
|
for (MockObjectRegistry::StateMap::iterator it =
|
||||||
|
g_mock_object_registry.states().begin();
|
||||||
|
it != g_mock_object_registry.states().end(); ++it) {
|
||||||
|
FunctionMockers& mockers = it->second.function_mockers;
|
||||||
|
if (mockers.erase(mocker) > 0) {
|
||||||
|
// mocker was in mockers and has been just removed.
|
||||||
|
if (mockers.empty()) {
|
||||||
|
g_mock_object_registry.states().erase(it);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clears all ON_CALL()s set on the given mock object.
|
||||||
|
void Mock::ClearDefaultActionsLocked(void* mock_obj)
|
||||||
|
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||||
|
internal::g_gmock_mutex.AssertHeld();
|
||||||
|
|
||||||
|
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||||
|
// No ON_CALL() was set on the given mock object.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clears the default actions for each mock method in the given mock
|
||||||
|
// object.
|
||||||
|
FunctionMockers& mockers =
|
||||||
|
g_mock_object_registry.states()[mock_obj].function_mockers;
|
||||||
|
for (FunctionMockers::const_iterator it = mockers.begin();
|
||||||
|
it != mockers.end(); ++it) {
|
||||||
|
(*it)->ClearDefaultActionsLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't clear the content of mockers, as they may still be
|
||||||
|
// needed by VerifyAndClearExpectationsLocked().
|
||||||
|
}
|
||||||
|
|
||||||
|
Expectation::Expectation() {}
|
||||||
|
|
||||||
|
Expectation::Expectation(
|
||||||
|
const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
|
||||||
|
: expectation_base_(an_expectation_base) {}
|
||||||
|
|
||||||
|
Expectation::~Expectation() {}
|
||||||
|
|
||||||
|
// Adds an expectation to a sequence.
|
||||||
|
void Sequence::AddExpectation(const Expectation& expectation) const {
|
||||||
|
if (*last_expectation_ != expectation) {
|
||||||
|
if (last_expectation_->expectation_base() != NULL) {
|
||||||
|
expectation.expectation_base()->immediate_prerequisites_
|
||||||
|
+= *last_expectation_;
|
||||||
|
}
|
||||||
|
*last_expectation_ = expectation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates the implicit sequence if there isn't one.
|
||||||
|
InSequence::InSequence() {
|
||||||
|
if (internal::g_gmock_implicit_sequence.get() == NULL) {
|
||||||
|
internal::g_gmock_implicit_sequence.set(new Sequence);
|
||||||
|
sequence_created_ = true;
|
||||||
|
} else {
|
||||||
|
sequence_created_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deletes the implicit sequence if it was created by the constructor
|
||||||
|
// of this object.
|
||||||
|
InSequence::~InSequence() {
|
||||||
|
if (sequence_created_) {
|
||||||
|
delete internal::g_gmock_implicit_sequence.get();
|
||||||
|
internal::g_gmock_implicit_sequence.set(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
182
gmock/src/gmock.cc
Normal file
182
gmock/src/gmock.cc
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "gmock/internal/gmock-port.h"
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
// TODO(wan@google.com): support using environment variables to
|
||||||
|
// control the flag values, like what Google Test does.
|
||||||
|
|
||||||
|
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
|
||||||
|
"true iff Google Mock should report leaked mock objects "
|
||||||
|
"as failures.");
|
||||||
|
|
||||||
|
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
|
||||||
|
"Controls how verbose Google Mock's output is."
|
||||||
|
" Valid values:\n"
|
||||||
|
" info - prints all messages.\n"
|
||||||
|
" warning - prints warnings and errors.\n"
|
||||||
|
" error - prints errors only.");
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Parses a string as a command line flag. The string should have the
|
||||||
|
// format "--gmock_flag=value". When def_optional is true, the
|
||||||
|
// "=value" part can be omitted.
|
||||||
|
//
|
||||||
|
// Returns the value of the flag, or NULL if the parsing failed.
|
||||||
|
static const char* ParseGoogleMockFlagValue(const char* str,
|
||||||
|
const char* flag,
|
||||||
|
bool def_optional) {
|
||||||
|
// str and flag must not be NULL.
|
||||||
|
if (str == NULL || flag == NULL) return NULL;
|
||||||
|
|
||||||
|
// The flag must start with "--gmock_".
|
||||||
|
const std::string flag_str = std::string("--gmock_") + flag;
|
||||||
|
const size_t flag_len = flag_str.length();
|
||||||
|
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
|
||||||
|
|
||||||
|
// Skips the flag name.
|
||||||
|
const char* flag_end = str + flag_len;
|
||||||
|
|
||||||
|
// When def_optional is true, it's OK to not have a "=value" part.
|
||||||
|
if (def_optional && (flag_end[0] == '\0')) {
|
||||||
|
return flag_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If def_optional is true and there are more characters after the
|
||||||
|
// flag name, or if def_optional is false, there must be a '=' after
|
||||||
|
// the flag name.
|
||||||
|
if (flag_end[0] != '=') return NULL;
|
||||||
|
|
||||||
|
// Returns the string after "=".
|
||||||
|
return flag_end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses a string for a Google Mock bool flag, in the form of
|
||||||
|
// "--gmock_flag=value".
|
||||||
|
//
|
||||||
|
// On success, stores the value of the flag in *value, and returns
|
||||||
|
// true. On failure, returns false without changing *value.
|
||||||
|
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||||
|
bool* value) {
|
||||||
|
// Gets the value of the flag as a string.
|
||||||
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
|
||||||
|
|
||||||
|
// Aborts if the parsing failed.
|
||||||
|
if (value_str == NULL) return false;
|
||||||
|
|
||||||
|
// Converts the string value to a bool.
|
||||||
|
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses a string for a Google Mock string flag, in the form of
|
||||||
|
// "--gmock_flag=value".
|
||||||
|
//
|
||||||
|
// On success, stores the value of the flag in *value, and returns
|
||||||
|
// true. On failure, returns false without changing *value.
|
||||||
|
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||||
|
std::string* value) {
|
||||||
|
// Gets the value of the flag as a string.
|
||||||
|
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
||||||
|
|
||||||
|
// Aborts if the parsing failed.
|
||||||
|
if (value_str == NULL) return false;
|
||||||
|
|
||||||
|
// Sets *value to the value of the flag.
|
||||||
|
*value = value_str;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The internal implementation of InitGoogleMock().
|
||||||
|
//
|
||||||
|
// The type parameter CharType can be instantiated to either char or
|
||||||
|
// wchar_t.
|
||||||
|
template <typename CharType>
|
||||||
|
void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||||
|
// Makes sure Google Test is initialized. InitGoogleTest() is
|
||||||
|
// idempotent, so it's fine if the user has already called it.
|
||||||
|
InitGoogleTest(argc, argv);
|
||||||
|
if (*argc <= 0) return;
|
||||||
|
|
||||||
|
for (int i = 1; i != *argc; i++) {
|
||||||
|
const std::string arg_string = StreamableToString(argv[i]);
|
||||||
|
const char* const arg = arg_string.c_str();
|
||||||
|
|
||||||
|
// Do we see a Google Mock flag?
|
||||||
|
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
|
||||||
|
&GMOCK_FLAG(catch_leaked_mocks)) ||
|
||||||
|
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
|
||||||
|
// Yes. Shift the remainder of the argv list left by one. Note
|
||||||
|
// that argv has (*argc + 1) elements, the last one always being
|
||||||
|
// NULL. The following loop moves the trailing NULL element as
|
||||||
|
// well.
|
||||||
|
for (int j = i; j != *argc; j++) {
|
||||||
|
argv[j] = argv[j + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrements the argument count.
|
||||||
|
(*argc)--;
|
||||||
|
|
||||||
|
// We also need to decrement the iterator as we just removed
|
||||||
|
// an element.
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
// Initializes Google Mock. This must be called before running the
|
||||||
|
// tests. In particular, it parses a command line for the flags that
|
||||||
|
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is
|
||||||
|
// removed from argv, and *argc is decremented.
|
||||||
|
//
|
||||||
|
// No value is returned. Instead, the Google Mock flag variables are
|
||||||
|
// updated.
|
||||||
|
//
|
||||||
|
// Since Google Test is needed for Google Mock to work, this function
|
||||||
|
// also initializes Google Test and parses its flags, if that hasn't
|
||||||
|
// been done.
|
||||||
|
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
|
||||||
|
internal::InitGoogleMockImpl(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This overloaded version can be used in Windows programs compiled in
|
||||||
|
// UNICODE mode.
|
||||||
|
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||||
|
internal::InitGoogleMockImpl(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
54
gmock/src/gmock_main.cc
Normal file
54
gmock/src/gmock_main.cc
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2008, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: wan@google.com (Zhanyong Wan)
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
|
||||||
|
// causes a link error when _tmain is defined in a static library and UNICODE
|
||||||
|
// is enabled. For this reason instead of _tmain, main function is used on
|
||||||
|
// Windows. See the following link to track the current status of this bug:
|
||||||
|
// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
|
||||||
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
|
# include <tchar.h> // NOLINT
|
||||||
|
|
||||||
|
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||||
|
#else
|
||||||
|
GTEST_API_ int main(int argc, char** argv) {
|
||||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
std::cout << "Running main() from gmock_main.cc\n";
|
||||||
|
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||||
|
// also responsible for initializing Google Test. Therefore there's
|
||||||
|
// no need for calling testing::InitGoogleTest() separately.
|
||||||
|
testing::InitGoogleMock(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
|||||||
#Mon Aug 22 20:26:07 PDT 2016
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
|
||||||
|
|||||||
23
gradlew
vendored
23
gradlew
vendored
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
##
|
||||||
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
|
|||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
|
|
||||||
warn ( ) {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
}
|
||||||
|
|
||||||
die ( ) {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
@@ -154,16 +154,19 @@ if $cygwin ; then
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
# Escape application args
|
||||||
function splitJvmOpts() {
|
save () {
|
||||||
JVM_OPTS=("$@")
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
}
|
}
|
||||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
APP_ARGS=$(save "$@")
|
||||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|||||||
43
hal/.styleguide
Normal file
43
hal/.styleguide
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
cppHeaderFileInclude {
|
||||||
|
\.h$
|
||||||
|
\.hpp$
|
||||||
|
\.inc$
|
||||||
|
}
|
||||||
|
|
||||||
|
cppSrcFileInclude {
|
||||||
|
\.cpp$
|
||||||
|
}
|
||||||
|
|
||||||
|
generatedFileExclude {
|
||||||
|
gmock/
|
||||||
|
ni-libraries/include/
|
||||||
|
ni-libraries/lib/
|
||||||
|
hal/src/main/native/athena/ctre/
|
||||||
|
hal/src/main/native/athena/frccansae/
|
||||||
|
hal/src/main/native/athena/visa/
|
||||||
|
hal/src/main/native/include/ctre/
|
||||||
|
UsageReporting\.h$
|
||||||
|
}
|
||||||
|
|
||||||
|
modifiableFileExclude {
|
||||||
|
wpilibj/src/arm-linux-jni/
|
||||||
|
wpilibj/src/main/native/cpp/
|
||||||
|
\.patch$
|
||||||
|
\.png$
|
||||||
|
\.py$
|
||||||
|
\.so$
|
||||||
|
}
|
||||||
|
|
||||||
|
includeOtherLibs {
|
||||||
|
^FRC_FPGA_ChipObject/
|
||||||
|
^FRC_NetworkCommunication/
|
||||||
|
^i2clib/
|
||||||
|
^llvm/
|
||||||
|
^opencv2/
|
||||||
|
^spilib/
|
||||||
|
^support/
|
||||||
|
}
|
||||||
|
|
||||||
|
includeProject {
|
||||||
|
^ctre/
|
||||||
|
}
|
||||||
367
hal/build.gradle
367
hal/build.gradle
@@ -1,187 +1,222 @@
|
|||||||
// There are two hal libraries that are built
|
apply plugin: 'cpp'
|
||||||
// - desktop which is used by simulation (gcc/msvc)
|
apply plugin: 'google-test'
|
||||||
// - athena which is used by the roborio (arm)
|
apply plugin: 'visual-studio'
|
||||||
|
apply plugin: 'edu.wpi.first.NativeUtils'
|
||||||
|
|
||||||
plugins {
|
apply from: '../config.gradle'
|
||||||
id 'cpp'
|
|
||||||
id 'maven-publish'
|
|
||||||
}
|
|
||||||
|
|
||||||
defineWpiUtilProperties()
|
ext.addHalToLinker = { binary->
|
||||||
|
if (binary.targetPlatform.architecture.name == 'athena') {
|
||||||
debugStripSetup(project)
|
binary.lib project: ':hal', library: 'halAthena', linkage: 'shared'
|
||||||
|
} else {
|
||||||
model {
|
binary.lib project: ':hal', library: 'halSim', linkage: 'shared'
|
||||||
components {
|
|
||||||
HALAthena(NativeLibrarySpec) {
|
|
||||||
targetPlatform 'arm'
|
|
||||||
binaries.all {
|
|
||||||
tasks.withType(CppCompile) {
|
|
||||||
addNiLibraryLinks(linker, targetPlatform)
|
|
||||||
addWpiUtilLibraryLinks(it, linker, targetPlatform)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sources {
|
|
||||||
cpp {
|
|
||||||
source {
|
|
||||||
srcDirs = ["lib/athena", "lib/athena/FRC_FPGA_ChipObject", "lib/shared"]
|
|
||||||
includes = ["**/*.cpp"]
|
|
||||||
}
|
|
||||||
exportedHeaders {
|
|
||||||
srcDirs = ["include", "lib/athena/FRC_FPGA_ChipObject", wpiUtilInclude]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HALSim(NativeLibrarySpec) {
|
|
||||||
// binaries.all {
|
|
||||||
// if (toolChain in Gcc){
|
|
||||||
// cppCompiler.args "-std=c++1y"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// sources {
|
|
||||||
// cpp {
|
|
||||||
// source {
|
|
||||||
// srcDirs = ["lib/sim", "lib/shared"]
|
|
||||||
// includes = ["**/*.cpp"]
|
|
||||||
// }
|
|
||||||
// exportedHeaders {
|
|
||||||
// srcDirs = ["include", "lib/sim", "lib/shared"]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task halZip(type: Zip) {
|
model {
|
||||||
description = 'Zips the HAL'
|
dependencyConfigs {
|
||||||
group = 'WPILib'
|
wpiutil(DependencyConfig) {
|
||||||
baseName = 'hal'
|
groupId = 'edu.wpi.first.wpiutil'
|
||||||
destinationDir = project.buildDir
|
artifactId = 'wpiutil-cpp'
|
||||||
duplicatesStrategy = 'exclude'
|
headerClassifier = 'headers'
|
||||||
|
ext = 'zip'
|
||||||
// Include the shared library file and header files from this project
|
version = '3.+'
|
||||||
model {
|
sharedConfigs = [ halAthena: [], halSim: [], halDev: [], halSimTestingBaseTest: [] ]
|
||||||
binaries {
|
staticConfigs = [ halSimStaticDeps: [] ]
|
||||||
withType(SharedLibraryBinarySpec) { spec ->
|
}
|
||||||
spec.headerDirs.each {
|
}
|
||||||
def normalizedIt = it.toString().replace('/', '\\')
|
// Exports config is a utility to enable exporting all symbols in a C++ library on windows to a DLL.
|
||||||
def normalizedWPIUtil = wpiUtilInclude.toString().replace('/', '\\')
|
// This removes the need for DllExport on a library. However, the gradle C++ builder has a bug
|
||||||
if (normalizedIt != normalizedWPIUtil) {
|
// where some extra symbols are added that cannot be resolved at link time. This configuration
|
||||||
from(it) {
|
// lets you specify specific symbols to exlude from exporting.
|
||||||
into 'include'
|
exportsConfigs {
|
||||||
// We don't want to include any of the .cpp files that are in some of the header directories
|
halSim(ExportsConfig) {
|
||||||
exclude '**/*.cpp'
|
x86ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
|
||||||
|
'_CT??_R0?AVbad_cast',
|
||||||
|
'_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
|
||||||
|
'_TI5?AVfailure' ]
|
||||||
|
x64ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
|
||||||
|
'_CT??_R0?AVbad_cast',
|
||||||
|
'_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
|
||||||
|
'_TI5?AVfailure' ]
|
||||||
|
}
|
||||||
|
halSimStaticDeps(ExportsConfig) {
|
||||||
|
x86SymbolFilter = { symbols->
|
||||||
|
def retList = []
|
||||||
|
symbols.each { symbol->
|
||||||
|
if (symbol.startsWith('HAL_')) {
|
||||||
|
retList << symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retList
|
||||||
|
}
|
||||||
|
x64SymbolFilter = { symbols->
|
||||||
|
def retList = []
|
||||||
|
symbols.each { symbol->
|
||||||
|
if (symbol.startsWith('HAL_')) {
|
||||||
|
retList << symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
components {
|
||||||
|
if (!project.hasProperty('skipAthena')) {
|
||||||
|
halAthena(NativeLibrarySpec) {
|
||||||
|
baseName = 'wpiHal'
|
||||||
|
sources {
|
||||||
|
cpp {
|
||||||
|
source {
|
||||||
|
srcDirs = [ 'src/main/native/shared', 'src/main/native/athena' ]
|
||||||
|
includes = ["**/*.cpp"]
|
||||||
|
}
|
||||||
|
exportedHeaders {
|
||||||
|
srcDirs = ["src/main/native/include"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
from(spec.sharedLibraryFile) {
|
binaries.all { binary->
|
||||||
into 'lib'
|
if (binary.targetPlatform.architecture.name != 'athena') {
|
||||||
}
|
binary.buildable = false
|
||||||
from(new File(spec.sharedLibraryFile.absolutePath + ".debug")) {
|
|
||||||
into 'lib'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, include all of the shared library objects from the ni directory
|
|
||||||
from(project.file('../ni-libraries')) {
|
|
||||||
into 'lib'
|
|
||||||
exclude 'genlinks'
|
|
||||||
exclude 'libwpi.so'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the hal static and shared libraries as a dependency
|
|
||||||
project(':hal').tasks.whenTaskAdded { task ->
|
|
||||||
if (task.name.toLowerCase() == 'halathenastaticlibrary' || task.name.toLowerCase() == 'halathenasharedlibrary') {
|
|
||||||
halZip.dependsOn task
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task athenaRuntimeZip(type: Zip) {
|
|
||||||
description = 'Zips the Athena Runtime libraries'
|
|
||||||
group = 'WPILib'
|
|
||||||
baseName = 'athena-runtime'
|
|
||||||
destinationDir = project.buildDir
|
|
||||||
duplicatesStrategy = 'exclude'
|
|
||||||
|
|
||||||
// Include the static library file and header files from this project
|
|
||||||
model {
|
|
||||||
binaries {
|
|
||||||
withType(SharedLibraryBinarySpec) { spec ->
|
|
||||||
spec.headerDirs.each {
|
|
||||||
from(it) {
|
|
||||||
into 'include'
|
|
||||||
// We don't want to include any of the .cpp files that are in some of the header directories
|
|
||||||
exclude '**/*.cpp'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
from(spec.sharedLibraryFile) {
|
}
|
||||||
into 'lib'
|
}
|
||||||
|
if (!project.hasProperty('onlyAthena')) {
|
||||||
|
halSim(NativeLibrarySpec) {
|
||||||
|
baseName = 'wpiHal'
|
||||||
|
sources {
|
||||||
|
cpp {
|
||||||
|
source {
|
||||||
|
srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
|
||||||
|
includes = ["**/*.cpp"]
|
||||||
|
}
|
||||||
|
exportedHeaders {
|
||||||
|
srcDirs = ["src/main/native/include"]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
from(new File(spec.sharedLibraryFile.absolutePath + ".debug")) {
|
binaries.all { binary ->
|
||||||
into 'lib'
|
if (binary.targetPlatform.operatingSystem.linux) {
|
||||||
|
linker.args "-ldl"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (project.hasProperty('buildHalStaticDeps')) {
|
||||||
|
halSimStaticDeps(NativeLibrarySpec) {
|
||||||
|
baseName = 'wpiHal'
|
||||||
|
binaries {
|
||||||
|
withType(StaticLibraryBinarySpec) {
|
||||||
|
buildable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sources {
|
||||||
|
cpp {
|
||||||
|
source {
|
||||||
|
srcDirs = [ 'src/main/native/shared', 'src/main/native/sim' ]
|
||||||
|
includes = ["**/*.cpp"]
|
||||||
|
}
|
||||||
|
exportedHeaders {
|
||||||
|
srcDirs = ["src/main/native/include"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The TestingBase library is a workaround for an issue with the GoogleTest plugin.
|
||||||
|
// The plugin by default will rebuild the entire test source set, which increases
|
||||||
|
// build time. By testing an empty library, and then just linking the already built component
|
||||||
|
// into the test, we save the extra build
|
||||||
|
halSimTestingBase(NativeLibrarySpec) { }
|
||||||
|
// By default, a development executable will be generated. This is to help the case of
|
||||||
|
// testing specific functionality of the library.
|
||||||
|
if (!project.hasProperty('skipDevExe')) {
|
||||||
|
halDev(NativeExecutableSpec) {
|
||||||
|
binaries.all {
|
||||||
|
project.addHalToLinker(it)
|
||||||
|
}
|
||||||
|
sources {
|
||||||
|
cpp {
|
||||||
|
source {
|
||||||
|
srcDirs 'src/dev/native/cpp'
|
||||||
|
include '**/*.cpp'
|
||||||
|
}
|
||||||
|
exportedHeaders {
|
||||||
|
srcDirs 'src/dev/native/include'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
testSuites {
|
||||||
defineNetworkTablesProperties()
|
halSimTestingBaseTest {
|
||||||
|
sources {
|
||||||
from(project.file(netTablesInclude)) {
|
cpp.source.srcDir 'src/test/native/cpp'
|
||||||
into 'include'
|
cpp.exportedHeaders.srcDir 'src/test/native/include'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
binaries {
|
||||||
from (file(netSharedLib)) {
|
all {
|
||||||
into 'lib'
|
project(':ni-libraries').addNiLibrariesToLinker(it)
|
||||||
|
}
|
||||||
|
withType(GoogleTestTestSuiteBinarySpec) {
|
||||||
|
if (it.component.testedComponent.name.contains('TestingBase') && !project.hasProperty('onlyAthena')) {
|
||||||
|
project(':gmock').addGmockToLinker(it)
|
||||||
|
project.addHalToLinker(it)
|
||||||
|
} else {
|
||||||
|
it.buildable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
tasks {
|
||||||
from (file(netSharedLibDebug)) {
|
runCpp(Exec) {
|
||||||
into 'lib'
|
def found = false
|
||||||
}
|
$.components.each {
|
||||||
|
if (it in NativeExecutableSpec && it.name == 'halDev') {
|
||||||
from (file(wpiUtilSharedLib)) {
|
it.binaries.each {
|
||||||
into 'lib'
|
if (!found) {
|
||||||
}
|
def arch = it.targetPlatform.architecture.name
|
||||||
|
if (arch == 'x86-64' || arch == 'x86') {
|
||||||
from (file(wpiUtilSharedLibDebug)) {
|
dependsOn it.tasks.install
|
||||||
into 'lib'
|
commandLine it.tasks.install.runScript
|
||||||
}
|
found = true
|
||||||
|
}
|
||||||
// Add the hal static and shared libraries as a dependency
|
}
|
||||||
project(':hal').tasks.whenTaskAdded { task ->
|
}
|
||||||
if (task.name.toLowerCase() == 'halathenastaticlibrary' || task.name.toLowerCase() == 'halathenasharedlibrary') {
|
}
|
||||||
athenaRuntimeZip.dependsOn task
|
}
|
||||||
|
}
|
||||||
|
getHeaders(Task) {
|
||||||
|
def list = []
|
||||||
|
$.components.each {
|
||||||
|
if (it in NativeLibrarySpec && (it.name == 'halAthena' || it.name == 'halSim')) {
|
||||||
|
it.sources.each {
|
||||||
|
it.exportedHeaders.srcDirs.each {
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it.binaries.each {
|
||||||
|
it.libs.each {
|
||||||
|
it.includeRoots.each {
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = list.unique(false)
|
||||||
|
doLast {
|
||||||
|
list.each {
|
||||||
|
print "WPIHEADER: "
|
||||||
|
println it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply from: 'publish.gradle'
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
hal(MavenPublication) {
|
|
||||||
artifact halZip
|
|
||||||
|
|
||||||
groupId 'edu.wpi.first.wpilib'
|
|
||||||
artifactId 'hal'
|
|
||||||
version WPILibVersion.version
|
|
||||||
}
|
|
||||||
athenaruntime(MavenPublication) {
|
|
||||||
artifact athenaRuntimeZip
|
|
||||||
|
|
||||||
groupId 'edu.wpi.first.wpilib'
|
|
||||||
artifactId 'athena-runtime'
|
|
||||||
version WPILibVersion.version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setupWpilibRepo(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
build.dependsOn halZip
|
|
||||||
build.dependsOn athenaRuntimeZip
|
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
// CANSessionMux.h
|
|
||||||
//
|
|
||||||
// Defines the API for building a CAN Interface Plugin to support
|
|
||||||
// PWM-cable-free CAN motor control on FRC robots. This allows you
|
|
||||||
// to connect any CAN interface to the secure Jaguar CAN driver.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __CANSessionMux_h__
|
|
||||||
#define __CANSessionMux_h__
|
|
||||||
|
|
||||||
#if defined(__vxworks)
|
|
||||||
#include <vxWorks.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CAN_SEND_PERIOD_NO_REPEAT 0
|
|
||||||
#define CAN_SEND_PERIOD_STOP_REPEATING -1
|
|
||||||
|
|
||||||
/* Flags in the upper bits of the messageID */
|
|
||||||
#define CAN_IS_FRAME_REMOTE 0x80000000
|
|
||||||
#define CAN_IS_FRAME_11BIT 0x40000000
|
|
||||||
|
|
||||||
#define ERR_CANSessionMux_InvalidBuffer -44086
|
|
||||||
#define ERR_CANSessionMux_MessageNotFound -44087
|
|
||||||
#define WARN_CANSessionMux_NoToken 44087
|
|
||||||
#define ERR_CANSessionMux_NotAllowed -44088
|
|
||||||
#define ERR_CANSessionMux_NotInitialized -44089
|
|
||||||
#define ERR_CANSessionMux_SessionOverrun 44050
|
|
||||||
|
|
||||||
struct tCANStreamMessage{
|
|
||||||
uint32_t messageID;
|
|
||||||
uint32_t timeStamp;
|
|
||||||
uint8_t data[8];
|
|
||||||
uint8_t dataSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
namespace nCANSessionMux
|
|
||||||
{
|
|
||||||
void sendMessage_wrapper(uint32_t messageID, const uint8_t *data, uint8_t dataSize, int32_t periodMs, int32_t *status);
|
|
||||||
void receiveMessage_wrapper(uint32_t *messageID, uint32_t messageIDMask, uint8_t *data, uint8_t *dataSize, uint32_t *timeStamp, int32_t *status);
|
|
||||||
void openStreamSession(uint32_t *sessionHandle, uint32_t messageID, uint32_t messageIDMask, uint32_t maxMessages, int32_t *status);
|
|
||||||
void closeStreamSession(uint32_t sessionHandle);
|
|
||||||
void readStreamSession(uint32_t sessionHandle, struct tCANStreamMessage *messages, uint32_t messagesToRead, uint32_t *messagesRead, int32_t *status);
|
|
||||||
void getCANStatus(float *percentBusUtilization, uint32_t *busOffCount, uint32_t *txFullCount, uint32_t *receiveErrorCount, uint32_t *transmitErrorCount, int32_t *status);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FRC_NetworkCommunication_CANSessionMux_sendMessage(uint32_t messageID, const uint8_t *data, uint8_t dataSize, int32_t periodMs, int32_t *status);
|
|
||||||
void FRC_NetworkCommunication_CANSessionMux_receiveMessage(uint32_t *messageID, uint32_t messageIDMask, uint8_t *data, uint8_t *dataSize, uint32_t *timeStamp, int32_t *status);
|
|
||||||
void FRC_NetworkCommunication_CANSessionMux_openStreamSession(uint32_t *sessionHandle, uint32_t messageID, uint32_t messageIDMask, uint32_t maxMessages, int32_t *status);
|
|
||||||
void FRC_NetworkCommunication_CANSessionMux_closeStreamSession(uint32_t sessionHandle);
|
|
||||||
void FRC_NetworkCommunication_CANSessionMux_readStreamSession(uint32_t sessionHandle, struct tCANStreamMessage *messages, uint32_t messagesToRead, uint32_t *messagesRead, int32_t *status);
|
|
||||||
void FRC_NetworkCommunication_CANSessionMux_getCANStatus(float *percentBusUtilization, uint32_t *busOffCount, uint32_t *txFullCount, uint32_t *receiveErrorCount, uint32_t *transmitErrorCount, int32_t *status);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __CANSessionMux_h__
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
|
|
||||||
#ifndef __LoadOut_h__
|
|
||||||
#define __LoadOut_h__
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <vxWorks_compat.h>
|
|
||||||
#define EXPORT_FUNC __declspec(dllexport) __cdecl
|
|
||||||
#elif defined (__vxworks)
|
|
||||||
#include <vxWorks.h>
|
|
||||||
#define EXPORT_FUNC
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#define EXPORT_FUNC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define kMaxModuleNumber 2
|
|
||||||
namespace nLoadOut
|
|
||||||
{
|
|
||||||
#if defined(__vxworks) || defined(SIMULATION)
|
|
||||||
typedef enum {
|
|
||||||
kModuleType_Unknown = 0x00,
|
|
||||||
kModuleType_Analog = 0x01,
|
|
||||||
kModuleType_Digital = 0x02,
|
|
||||||
kModuleType_Solenoid = 0x03,
|
|
||||||
} tModuleType;
|
|
||||||
bool EXPORT_FUNC getModulePresence(tModuleType moduleType, uint8_t moduleNumber);
|
|
||||||
#endif
|
|
||||||
typedef enum {
|
|
||||||
kTargetClass_Unknown = 0x00,
|
|
||||||
kTargetClass_FRC1 = 0x10,
|
|
||||||
kTargetClass_FRC2 = 0x20,
|
|
||||||
kTargetClass_FRC3 = 0x30,
|
|
||||||
kTargetClass_RoboRIO = 0x40,
|
|
||||||
#if defined(__vxworks) || defined(SIMULATION)
|
|
||||||
kTargetClass_FRC2_Analog = kTargetClass_FRC2 | kModuleType_Analog,
|
|
||||||
kTargetClass_FRC2_Digital = kTargetClass_FRC2 | kModuleType_Digital,
|
|
||||||
kTargetClass_FRC2_Solenoid = kTargetClass_FRC2 | kModuleType_Solenoid,
|
|
||||||
#endif
|
|
||||||
kTargetClass_FamilyMask = 0xF0,
|
|
||||||
kTargetClass_ModuleMask = 0x0F,
|
|
||||||
} tTargetClass;
|
|
||||||
tTargetClass EXPORT_FUNC getTargetClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__vxworks) || defined(SIMULATION)
|
|
||||||
uint32_t EXPORT_FUNC FRC_NetworkCommunication_nLoadOut_getModulePresence(uint32_t moduleType, uint8_t moduleNumber);
|
|
||||||
#endif
|
|
||||||
uint32_t EXPORT_FUNC FRC_NetworkCommunication_nLoadOut_getTargetClass();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __LoadOut_h__
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
|
|
||||||
#ifndef __UsageReporting_h__
|
|
||||||
#define __UsageReporting_h__
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <vxWorks_compat.h>
|
|
||||||
#define EXPORT_FUNC __declspec(dllexport) __cdecl
|
|
||||||
#elif defined (__vxworks)
|
|
||||||
#include <vxWorks.h>
|
|
||||||
#define EXPORT_FUNC
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define EXPORT_FUNC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define kUsageReporting_version 1
|
|
||||||
|
|
||||||
namespace nUsageReporting
|
|
||||||
{
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
kResourceType_Controller,
|
|
||||||
kResourceType_Module,
|
|
||||||
kResourceType_Language,
|
|
||||||
kResourceType_CANPlugin,
|
|
||||||
kResourceType_Accelerometer,
|
|
||||||
kResourceType_ADXL345,
|
|
||||||
kResourceType_AnalogChannel,
|
|
||||||
kResourceType_AnalogTrigger,
|
|
||||||
kResourceType_AnalogTriggerOutput,
|
|
||||||
kResourceType_CANJaguar,
|
|
||||||
kResourceType_Compressor,
|
|
||||||
kResourceType_Counter,
|
|
||||||
kResourceType_Dashboard,
|
|
||||||
kResourceType_DigitalInput,
|
|
||||||
kResourceType_DigitalOutput,
|
|
||||||
kResourceType_DriverStationCIO,
|
|
||||||
kResourceType_DriverStationEIO,
|
|
||||||
kResourceType_DriverStationLCD,
|
|
||||||
kResourceType_Encoder,
|
|
||||||
kResourceType_GearTooth,
|
|
||||||
kResourceType_Gyro,
|
|
||||||
kResourceType_I2C,
|
|
||||||
kResourceType_Framework,
|
|
||||||
kResourceType_Jaguar,
|
|
||||||
kResourceType_Joystick,
|
|
||||||
kResourceType_Kinect,
|
|
||||||
kResourceType_KinectStick,
|
|
||||||
kResourceType_PIDController,
|
|
||||||
kResourceType_Preferences,
|
|
||||||
kResourceType_PWM,
|
|
||||||
kResourceType_Relay,
|
|
||||||
kResourceType_RobotDrive,
|
|
||||||
kResourceType_SerialPort,
|
|
||||||
kResourceType_Servo,
|
|
||||||
kResourceType_Solenoid,
|
|
||||||
kResourceType_SPI,
|
|
||||||
kResourceType_Task,
|
|
||||||
kResourceType_Ultrasonic,
|
|
||||||
kResourceType_Victor,
|
|
||||||
kResourceType_Button,
|
|
||||||
kResourceType_Command,
|
|
||||||
kResourceType_AxisCamera,
|
|
||||||
kResourceType_PCVideoServer,
|
|
||||||
kResourceType_SmartDashboard,
|
|
||||||
kResourceType_Talon,
|
|
||||||
kResourceType_HiTechnicColorSensor,
|
|
||||||
kResourceType_HiTechnicAccel,
|
|
||||||
kResourceType_HiTechnicCompass,
|
|
||||||
kResourceType_SRF08,
|
|
||||||
kResourceType_AnalogOutput,
|
|
||||||
kResourceType_VictorSP,
|
|
||||||
kResourceType_TalonSRX,
|
|
||||||
kResourceType_CANTalonSRX,
|
|
||||||
kResourceType_ADXL362,
|
|
||||||
kResourceType_ADXRS450,
|
|
||||||
kResourceType_RevSPARK,
|
|
||||||
kResourceType_MindsensorsSD540,
|
|
||||||
kResourceType_DigitalFilter,
|
|
||||||
} tResourceType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
kLanguage_LabVIEW = 1,
|
|
||||||
kLanguage_CPlusPlus = 2,
|
|
||||||
kLanguage_Java = 3,
|
|
||||||
kLanguage_Python = 4,
|
|
||||||
|
|
||||||
kCANPlugin_BlackJagBridge = 1,
|
|
||||||
kCANPlugin_2CAN = 2,
|
|
||||||
|
|
||||||
kFramework_Iterative = 1,
|
|
||||||
kFramework_Simple = 2,
|
|
||||||
kFramework_CommandControl = 3,
|
|
||||||
|
|
||||||
kRobotDrive_ArcadeStandard = 1,
|
|
||||||
kRobotDrive_ArcadeButtonSpin = 2,
|
|
||||||
kRobotDrive_ArcadeRatioCurve = 3,
|
|
||||||
kRobotDrive_Tank = 4,
|
|
||||||
kRobotDrive_MecanumPolar = 5,
|
|
||||||
kRobotDrive_MecanumCartesian = 6,
|
|
||||||
|
|
||||||
kDriverStationCIO_Analog = 1,
|
|
||||||
kDriverStationCIO_DigitalIn = 2,
|
|
||||||
kDriverStationCIO_DigitalOut = 3,
|
|
||||||
|
|
||||||
kDriverStationEIO_Acceleration = 1,
|
|
||||||
kDriverStationEIO_AnalogIn = 2,
|
|
||||||
kDriverStationEIO_AnalogOut = 3,
|
|
||||||
kDriverStationEIO_Button = 4,
|
|
||||||
kDriverStationEIO_LED = 5,
|
|
||||||
kDriverStationEIO_DigitalIn = 6,
|
|
||||||
kDriverStationEIO_DigitalOut = 7,
|
|
||||||
kDriverStationEIO_FixedDigitalOut = 8,
|
|
||||||
kDriverStationEIO_PWM = 9,
|
|
||||||
kDriverStationEIO_Encoder = 10,
|
|
||||||
kDriverStationEIO_TouchSlider = 11,
|
|
||||||
|
|
||||||
kADXL345_SPI = 1,
|
|
||||||
kADXL345_I2C = 2,
|
|
||||||
|
|
||||||
kCommand_Scheduler = 1,
|
|
||||||
|
|
||||||
kSmartDashboard_Instance = 1,
|
|
||||||
} tInstances;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report the usage of a resource of interest.
|
|
||||||
*
|
|
||||||
* @param resource one of the values in the tResourceType above (max value 51).
|
|
||||||
* @param instanceNumber an index that identifies the resource instance.
|
|
||||||
* @param context an optional additional context number for some cases (such as module number). Set to 0 to omit.
|
|
||||||
* @param feature a string to be included describing features in use on a specific resource. Setting the same resource more than once allows you to change the feature string.
|
|
||||||
*/
|
|
||||||
uint32_t EXPORT_FUNC report(tResourceType resource, uint8_t instanceNumber, uint8_t context = 0, const char *feature = NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t EXPORT_FUNC FRC_NetworkCommunication_nUsageReporting_report(uint8_t resource, uint8_t instanceNumber, uint8_t context, const char *feature);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __UsageReporting_h__
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "FRC_NetworkCommunication/CANSessionMux.h"
|
|
||||||
|
|
||||||
void canTxSend(uint32_t arbID, uint8_t length,
|
|
||||||
int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
|
|
||||||
|
|
||||||
void canTxPackInt8(uint32_t arbID, uint8_t offset, uint8_t value);
|
|
||||||
void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value);
|
|
||||||
void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value);
|
|
||||||
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value);
|
|
||||||
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value);
|
|
||||||
|
|
||||||
uint8_t canTxUnpackInt8(uint32_t arbID, uint8_t offset);
|
|
||||||
uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset);
|
|
||||||
uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset);
|
|
||||||
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset);
|
|
||||||
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset);
|
|
||||||
|
|
||||||
bool canRxReceive(uint32_t arbID);
|
|
||||||
|
|
||||||
uint8_t canRxUnpackInt8(uint32_t arbID, uint8_t offset);
|
|
||||||
uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset);
|
|
||||||
uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset);
|
|
||||||
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset);
|
|
||||||
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset);
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "HAL/Types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void HAL_InitializeSPI(int32_t port, int32_t* status);
|
|
||||||
int32_t HAL_TransactionSPI(int32_t port, uint8_t* dataToSend,
|
|
||||||
uint8_t* dataReceived, int32_t size);
|
|
||||||
int32_t HAL_WriteSPI(int32_t port, uint8_t* dataToSend, int32_t sendSize);
|
|
||||||
int32_t HAL_ReadSPI(int32_t port, uint8_t* buffer, int32_t count);
|
|
||||||
void HAL_CloseSPI(int32_t port);
|
|
||||||
void HAL_SetSPISpeed(int32_t port, int32_t speed);
|
|
||||||
void HAL_SetSPIOpts(int32_t port, HAL_Bool msbFirst, HAL_Bool sampleOnTrailing,
|
|
||||||
HAL_Bool clkIdleHigh);
|
|
||||||
void HAL_SetSPIChipSelectActiveHigh(int32_t port, int32_t* status);
|
|
||||||
void HAL_SetSPIChipSelectActiveLow(int32_t port, int32_t* status);
|
|
||||||
int32_t HAL_GetSPIHandle(int32_t port);
|
|
||||||
void HAL_SetSPIHandle(int32_t port, int32_t handle);
|
|
||||||
|
|
||||||
void HAL_InitSPIAccumulator(int32_t port, int32_t period, int32_t cmd,
|
|
||||||
int32_t xferSize, int32_t validMask,
|
|
||||||
int32_t validValue, int32_t dataShift,
|
|
||||||
int32_t dataSize, HAL_Bool isSigned,
|
|
||||||
HAL_Bool bigEndian, int32_t* status);
|
|
||||||
void HAL_FreeSPIAccumulator(int32_t port, int32_t* status);
|
|
||||||
void HAL_ResetSPIAccumulator(int32_t port, int32_t* status);
|
|
||||||
void HAL_SetSPIAccumulatorCenter(int32_t port, int32_t center, int32_t* status);
|
|
||||||
void HAL_SetSPIAccumulatorDeadband(int32_t port, int32_t deadband,
|
|
||||||
int32_t* status);
|
|
||||||
int32_t HAL_GetSPIAccumulatorLastValue(int32_t port, int32_t* status);
|
|
||||||
int64_t HAL_GetSPIAccumulatorValue(int32_t port, int32_t* status);
|
|
||||||
int64_t HAL_GetSPIAccumulatorCount(int32_t port, int32_t* status);
|
|
||||||
double HAL_GetSPIAccumulatorAverage(int32_t port, int32_t* status);
|
|
||||||
void HAL_GetSPIAccumulatorOutput(int32_t port, int64_t* value, int64_t* count,
|
|
||||||
int32_t* status);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void HAL_InitializeSerialPort(int32_t port, int32_t* status);
|
|
||||||
void HAL_SetSerialBaudRate(int32_t port, int32_t baud, int32_t* status);
|
|
||||||
void HAL_SetSerialDataBits(int32_t port, int32_t bits, int32_t* status);
|
|
||||||
void HAL_SetSerialParity(int32_t port, int32_t parity, int32_t* status);
|
|
||||||
void HAL_SetSerialStopBits(int32_t port, int32_t stopBits, int32_t* status);
|
|
||||||
void HAL_SetSerialWriteMode(int32_t port, int32_t mode, int32_t* status);
|
|
||||||
void HAL_SetSerialFlowControl(int32_t port, int32_t flow, int32_t* status);
|
|
||||||
void HAL_SetSerialTimeout(int32_t port, double timeout, int32_t* status);
|
|
||||||
void HAL_EnableSerialTermination(int32_t port, char terminator,
|
|
||||||
int32_t* status);
|
|
||||||
void HAL_DisableSerialTermination(int32_t port, int32_t* status);
|
|
||||||
void HAL_SetSerialReadBufferSize(int32_t port, int32_t size, int32_t* status);
|
|
||||||
void HAL_SetSerialWriteBufferSize(int32_t port, int32_t size, int32_t* status);
|
|
||||||
int32_t HAL_GetSerialBytesReceived(int32_t port, int32_t* status);
|
|
||||||
int32_t HAL_ReadSerial(int32_t port, char* buffer, int32_t count,
|
|
||||||
int32_t* status);
|
|
||||||
int32_t HAL_WriteSerial(int32_t port, const char* buffer, int32_t count,
|
|
||||||
int32_t* status);
|
|
||||||
void HAL_FlushSerial(int32_t port, int32_t* status);
|
|
||||||
void HAL_ClearSerial(int32_t port, int32_t* status);
|
|
||||||
void HAL_CloseSerial(int32_t port, int32_t* status);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifndef _STATUS_DEFINED
|
|
||||||
#define _STATUS_DEFINED
|
|
||||||
typedef int32_t STATUS;
|
|
||||||
#endif /* _STATUS_DEFINED */
|
|
||||||
|
|
||||||
#ifndef OK
|
|
||||||
#define OK 0
|
|
||||||
#endif /* OK */
|
|
||||||
#ifndef ERROR
|
|
||||||
#define ERROR (-1)
|
|
||||||
#endif /* ERROR */
|
|
||||||
|
|
||||||
typedef pthread_t* TASK;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
// Note: These constants used to be declared extern and were defined in
|
|
||||||
// Task.cpp. This caused issues with the JNI bindings for java, and so the
|
|
||||||
// instantiations were moved here.
|
|
||||||
const int32_t HAL_TaskLib_ILLEGAL_PRIORITY = 22; // 22 is EINVAL
|
|
||||||
|
|
||||||
STATUS HAL_VerifyTaskID(TASK task);
|
|
||||||
|
|
||||||
// valid priority [1..99]
|
|
||||||
STATUS HAL_SetTaskPriority(TASK task, int32_t priority);
|
|
||||||
|
|
||||||
STATUS HAL_GetTaskPriority(TASK task, int32_t* priority);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
#include "HAL/cpp/priority_mutex.h"
|
|
||||||
|
|
||||||
class Semaphore {
|
|
||||||
public:
|
|
||||||
explicit Semaphore(int32_t count = 0);
|
|
||||||
Semaphore(Semaphore&&);
|
|
||||||
Semaphore& operator=(Semaphore&&);
|
|
||||||
|
|
||||||
void give();
|
|
||||||
void take();
|
|
||||||
|
|
||||||
// @return true if semaphore was locked successfully. false if not.
|
|
||||||
bool tryTake();
|
|
||||||
|
|
||||||
static const int32_t kNoWait = 0;
|
|
||||||
static const int32_t kWaitForever = -1;
|
|
||||||
|
|
||||||
static const int32_t kEmpty = 0;
|
|
||||||
static const int32_t kFull = 1;
|
|
||||||
|
|
||||||
private:
|
|
||||||
priority_mutex m_mutex;
|
|
||||||
std::condition_variable_any m_condition;
|
|
||||||
int32_t m_count = 0;
|
|
||||||
};
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/* std::condition_variable provides the native_handle() method to return its
|
|
||||||
* underlying pthread_cond_t*. WPILib uses this to interface with the FRC
|
|
||||||
* network communication library. Since WPILib uses a custom mutex class and
|
|
||||||
* not std::mutex, std::condition_variable_any must be used instead.
|
|
||||||
* std::condition_variable_any doesn't expose its internal handle, so this
|
|
||||||
* class provides the same interface and implementation in addition to a
|
|
||||||
* native_handle() method.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "priority_mutex.h"
|
|
||||||
|
|
||||||
class priority_condition_variable {
|
|
||||||
typedef std::chrono::system_clock clock;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef std::condition_variable::native_handle_type native_handle_type;
|
|
||||||
|
|
||||||
priority_condition_variable() : m_mutex(std::make_shared<std::mutex>()) {}
|
|
||||||
~priority_condition_variable() = default;
|
|
||||||
|
|
||||||
priority_condition_variable(const priority_condition_variable&) = delete;
|
|
||||||
priority_condition_variable& operator=(const priority_condition_variable&) =
|
|
||||||
delete;
|
|
||||||
|
|
||||||
void notify_one() noexcept {
|
|
||||||
std::lock_guard<std::mutex> lock(*m_mutex);
|
|
||||||
m_cond.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
void notify_all() noexcept {
|
|
||||||
std::lock_guard<std::mutex> lock(*m_mutex);
|
|
||||||
m_cond.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lock>
|
|
||||||
void wait(Lock& _lock) {
|
|
||||||
std::shared_ptr<std::mutex> _mutex = m_mutex;
|
|
||||||
std::unique_lock<std::mutex> my_lock(*_mutex);
|
|
||||||
Unlock<Lock> unlock(_lock);
|
|
||||||
|
|
||||||
// *mutex must be unlocked before re-locking _lock so move
|
|
||||||
// ownership of *_mutex lock to an object with shorter lifetime.
|
|
||||||
std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
|
|
||||||
m_cond.wait(my_lock2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lock, typename Predicate>
|
|
||||||
void wait(Lock& lock, Predicate p) {
|
|
||||||
while (!p()) {
|
|
||||||
wait(lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lock, typename Clock, typename Duration>
|
|
||||||
std::cv_status wait_until(
|
|
||||||
Lock& _lock, const std::chrono::time_point<Clock, Duration>& atime) {
|
|
||||||
std::shared_ptr<std::mutex> _mutex = m_mutex;
|
|
||||||
std::unique_lock<std::mutex> my_lock(*_mutex);
|
|
||||||
Unlock<Lock> unlock(_lock);
|
|
||||||
|
|
||||||
// *_mutex must be unlocked before re-locking _lock so move
|
|
||||||
// ownership of *_mutex lock to an object with shorter lifetime.
|
|
||||||
std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
|
|
||||||
return m_cond.wait_until(my_lock2, atime);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lock, typename Clock, typename Duration,
|
|
||||||
typename Predicate>
|
|
||||||
bool wait_until(Lock& lock,
|
|
||||||
const std::chrono::time_point<Clock, Duration>& atime,
|
|
||||||
Predicate p) {
|
|
||||||
while (!p()) {
|
|
||||||
if (wait_until(lock, atime) == std::cv_status::timeout) {
|
|
||||||
return p();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lock, typename Rep, typename Period>
|
|
||||||
std::cv_status wait_for(Lock& lock,
|
|
||||||
const std::chrono::duration<Rep, Period>& rtime) {
|
|
||||||
return wait_until(lock, clock::now() + rtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Lock, typename Rep, typename Period, typename Predicate>
|
|
||||||
bool wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& rtime,
|
|
||||||
Predicate p) {
|
|
||||||
return wait_until(lock, clock::now() + rtime, std::move(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
native_handle_type native_handle() { return m_cond.native_handle(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::condition_variable m_cond;
|
|
||||||
std::shared_ptr<std::mutex> m_mutex;
|
|
||||||
|
|
||||||
// scoped unlock - unlocks in ctor, re-locks in dtor
|
|
||||||
template <typename Lock>
|
|
||||||
struct Unlock {
|
|
||||||
explicit Unlock(Lock& lk) : m_lock(lk) { lk.unlock(); }
|
|
||||||
|
|
||||||
~Unlock() /*noexcept(false)*/ {
|
|
||||||
if (std::uncaught_exception()) {
|
|
||||||
try {
|
|
||||||
m_lock.lock();
|
|
||||||
} catch (...) {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_lock.lock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Unlock(const Unlock&) = delete;
|
|
||||||
Unlock& operator=(const Unlock&) = delete;
|
|
||||||
|
|
||||||
Lock& m_lock;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Allows usage with std::lock_guard without including <mutex> separately
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#ifdef FRC_SIMULATOR
|
|
||||||
// We do not want to use pthreads if in the simulator; however, in the
|
|
||||||
// simulator, we do not care about priority inversion.
|
|
||||||
typedef std::mutex priority_mutex;
|
|
||||||
typedef std::recursive_mutex priority_recursive_mutex;
|
|
||||||
#else // Covers rest of file.
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
class priority_recursive_mutex {
|
|
||||||
public:
|
|
||||||
typedef pthread_mutex_t* native_handle_type;
|
|
||||||
|
|
||||||
constexpr priority_recursive_mutex() noexcept = default;
|
|
||||||
priority_recursive_mutex(const priority_recursive_mutex&) = delete;
|
|
||||||
priority_recursive_mutex& operator=(const priority_recursive_mutex&) = delete;
|
|
||||||
|
|
||||||
// Lock the mutex, blocking until it's available.
|
|
||||||
void lock();
|
|
||||||
|
|
||||||
// Unlock the mutex.
|
|
||||||
void unlock();
|
|
||||||
|
|
||||||
// Tries to lock the mutex.
|
|
||||||
bool try_lock() noexcept;
|
|
||||||
|
|
||||||
pthread_mutex_t* native_handle();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Do the equivalent of setting PTHREAD_PRIO_INHERIT and
|
|
||||||
// PTHREAD_MUTEX_RECURSIVE_NP.
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
pthread_mutex_t m_mutex = {
|
|
||||||
{0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, 0, {0, 0}}};
|
|
||||||
#else
|
|
||||||
pthread_mutex_t m_mutex = {
|
|
||||||
{0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {0}}};
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class priority_mutex {
|
|
||||||
public:
|
|
||||||
typedef pthread_mutex_t* native_handle_type;
|
|
||||||
|
|
||||||
constexpr priority_mutex() noexcept = default;
|
|
||||||
priority_mutex(const priority_mutex&) = delete;
|
|
||||||
priority_mutex& operator=(const priority_mutex&) = delete;
|
|
||||||
|
|
||||||
// Lock the mutex, blocking until it's available.
|
|
||||||
void lock();
|
|
||||||
|
|
||||||
// Unlock the mutex.
|
|
||||||
void unlock();
|
|
||||||
|
|
||||||
// Tries to lock the mutex.
|
|
||||||
bool try_lock() noexcept;
|
|
||||||
|
|
||||||
pthread_mutex_t* native_handle();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Do the equivalent of setting PTHREAD_PRIO_INHERIT.
|
|
||||||
#if __WORDSIZE == 64
|
|
||||||
pthread_mutex_t m_mutex = {{0, 0, 0, 0, 0x20, 0, 0, {0, 0}}};
|
|
||||||
#else
|
|
||||||
pthread_mutex_t m_mutex = {{0, 0, 0, 0x20, 0, {0}}};
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FRC_SIMULATOR
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file ctre_frames.h
|
|
||||||
* CAN Encoder/Decoder Structures for CTRE devices.
|
|
||||||
*/
|
|
||||||
#ifndef CTRE_FRAMES_H
|
|
||||||
#define CTRE_FRAMES_H
|
|
||||||
|
|
||||||
/** control */
|
|
||||||
typedef struct _TALON_Control_1_General_10ms_t {
|
|
||||||
unsigned TokenH:8;
|
|
||||||
unsigned TokenL:8;
|
|
||||||
unsigned DemandH:8;
|
|
||||||
unsigned DemandM:8;
|
|
||||||
unsigned DemandL:8;
|
|
||||||
unsigned ProfileSlotSelect:1;
|
|
||||||
unsigned FeedbackDeviceSelect:4;
|
|
||||||
unsigned OverrideLimitSwitchEn:3;
|
|
||||||
unsigned RevFeedbackSensor:1;
|
|
||||||
unsigned RevMotDuringCloseLoopEn:1;
|
|
||||||
unsigned OverrideBrakeType:2;
|
|
||||||
unsigned ModeSelect:4;
|
|
||||||
unsigned RampThrottle:8;
|
|
||||||
} TALON_Control_1_General_10ms_t ;
|
|
||||||
|
|
||||||
/* TALON_Control_2_Rates_OneShot_t removed since it has been deprecated */
|
|
||||||
|
|
||||||
typedef struct _TALON_Control_3_ClearFlags_OneShot_t {
|
|
||||||
unsigned ZeroFeedbackSensor:1;
|
|
||||||
unsigned ClearStickyFaults:1;
|
|
||||||
} TALON_Control_3_ClearFlags_OneShot_t ;
|
|
||||||
|
|
||||||
typedef struct _TALON_Control_5_General_10ms_t {
|
|
||||||
unsigned ThrottleBump_h3:3;
|
|
||||||
unsigned ReservedZero:5;
|
|
||||||
unsigned ThrottleBump_l8:8;
|
|
||||||
unsigned DemandH:8;
|
|
||||||
unsigned DemandM:8;
|
|
||||||
unsigned DemandL:8;
|
|
||||||
unsigned ProfileSlotSelect:1;
|
|
||||||
unsigned FeedbackDeviceSelect:4;
|
|
||||||
unsigned OverrideLimitSwitchEn:3;
|
|
||||||
unsigned RevFeedbackSensor:1;
|
|
||||||
unsigned RevMotDuringCloseLoopEn:1;
|
|
||||||
unsigned OverrideBrakeType:2;
|
|
||||||
unsigned ModeSelect:4;
|
|
||||||
unsigned RampThrottle:8;
|
|
||||||
} TALON_Control_5_General_10ms_t ;
|
|
||||||
|
|
||||||
typedef struct _TALON_Control_6_MotProfAddTrajPoint_t {
|
|
||||||
unsigned huffCode:2; //!< Compression coding
|
|
||||||
unsigned NextPt_VelOnly:1;
|
|
||||||
unsigned NextPt_IsLast:1;
|
|
||||||
unsigned reserved0:2;
|
|
||||||
unsigned NextPt_ZeroPosition:1;
|
|
||||||
unsigned NextPt_ProfileSlotSelect:1;
|
|
||||||
unsigned Idx:4;
|
|
||||||
unsigned reserved1:4;
|
|
||||||
unsigned restOfFrame0:8;
|
|
||||||
unsigned restOfFrame1:8;
|
|
||||||
unsigned restOfFrame2:8;
|
|
||||||
unsigned restOfFrame3:8;
|
|
||||||
unsigned restOfFrame4:8;
|
|
||||||
unsigned restOfFrame5:8;
|
|
||||||
} TALON_Control_6_MotProfAddTrajPoint_t;
|
|
||||||
|
|
||||||
typedef struct _TALON_Control_6_MotProfAddTrajPoint_huff0_t {
|
|
||||||
unsigned huffCode_expect_0:2; //!< Compression coding
|
|
||||||
unsigned NextPt_VelOnly:1;
|
|
||||||
unsigned NextPt_IsLast:1;
|
|
||||||
unsigned reserved0:2;
|
|
||||||
unsigned NextPt_ZeroPosition:1;
|
|
||||||
unsigned NextPt_ProfileSlotSelect:1;
|
|
||||||
unsigned Idx:4;
|
|
||||||
unsigned reserved1:4;
|
|
||||||
unsigned NextPt_DurationMs:8;
|
|
||||||
unsigned NextPt_VelocityH:8;
|
|
||||||
unsigned NextPt_VelocityL:8;
|
|
||||||
unsigned NextPt_PositionH:8;
|
|
||||||
unsigned NextPt_PositionM:8;
|
|
||||||
unsigned NextPt_PositionL:8;
|
|
||||||
} TALON_Control_6_MotProfAddTrajPoint_huff0_t;
|
|
||||||
|
|
||||||
typedef struct _TALON_Control_6_MotProfAddTrajPoint_huff1_t {
|
|
||||||
unsigned huffCode_expect_1:2; //!< Compression coding
|
|
||||||
unsigned NextPt_VelOnly:1;
|
|
||||||
unsigned NextPt_IsLast:1;
|
|
||||||
unsigned reserved0:2;
|
|
||||||
unsigned NextPt_ZeroPosition:1;
|
|
||||||
unsigned NextPt_ProfileSlotSelect:1;
|
|
||||||
unsigned Idx:4;
|
|
||||||
unsigned reserved1:4;
|
|
||||||
unsigned NextPt_DurationMs:8;
|
|
||||||
unsigned NextPt_SameVelocityH:8;
|
|
||||||
unsigned NextPt_SameVelocityL:8;
|
|
||||||
unsigned NextPt_DeltaPositionH:8;
|
|
||||||
unsigned NextPt_DeltaPositionL:8;
|
|
||||||
unsigned NextPt_Count:8;
|
|
||||||
} TALON_Control_6_MotProfAddTrajPoint_huff1_t;
|
|
||||||
|
|
||||||
/** status */
|
|
||||||
typedef struct _TALON_Status_1_General_10ms_t {
|
|
||||||
unsigned CloseLoopErrH:8;
|
|
||||||
unsigned CloseLoopErrM:8;
|
|
||||||
unsigned CloseLoopErrL:8;
|
|
||||||
unsigned AppliedThrottle_h3:3;
|
|
||||||
unsigned Fault_RevSoftLim:1;
|
|
||||||
unsigned Fault_ForSoftLim:1;
|
|
||||||
unsigned TokLocked:1;
|
|
||||||
unsigned LimitSwitchClosedRev:1;
|
|
||||||
unsigned LimitSwitchClosedFor:1;
|
|
||||||
unsigned AppliedThrottle_l8:8;
|
|
||||||
unsigned ModeSelect_h1:1;
|
|
||||||
unsigned FeedbackDeviceSelect:4;
|
|
||||||
unsigned LimitSwitchEn:3;
|
|
||||||
unsigned Fault_HardwareFailure:1;
|
|
||||||
unsigned Fault_RevLim:1;
|
|
||||||
unsigned Fault_ForLim:1;
|
|
||||||
unsigned Fault_UnderVoltage:1;
|
|
||||||
unsigned Fault_OverTemp:1;
|
|
||||||
unsigned ModeSelect_b3:3;
|
|
||||||
unsigned TokenSeed:8;
|
|
||||||
} TALON_Status_1_General_10ms_t ;
|
|
||||||
typedef struct _TALON_Status_2_Feedback_20ms_t {
|
|
||||||
unsigned SensorPositionH:8;
|
|
||||||
unsigned SensorPositionM:8;
|
|
||||||
unsigned SensorPositionL:8;
|
|
||||||
unsigned SensorVelocityH:8;
|
|
||||||
unsigned SensorVelocityL:8;
|
|
||||||
unsigned Current_h8:8;
|
|
||||||
unsigned StckyFault_RevSoftLim:1;
|
|
||||||
unsigned StckyFault_ForSoftLim:1;
|
|
||||||
unsigned StckyFault_RevLim:1;
|
|
||||||
unsigned StckyFault_ForLim:1;
|
|
||||||
unsigned StckyFault_UnderVoltage:1;
|
|
||||||
unsigned StckyFault_OverTemp:1;
|
|
||||||
unsigned Current_l2:2;
|
|
||||||
unsigned reserved:3;
|
|
||||||
unsigned Cmd5Allowed:1;
|
|
||||||
unsigned VelDiv4:1;
|
|
||||||
unsigned PosDiv8:1;
|
|
||||||
unsigned ProfileSlotSelect:1;
|
|
||||||
unsigned BrakeIsEnabled:1;
|
|
||||||
} TALON_Status_2_Feedback_20ms_t ;
|
|
||||||
typedef struct _TALON_Status_3_Enc_100ms_t {
|
|
||||||
unsigned EncPositionH:8;
|
|
||||||
unsigned EncPositionM:8;
|
|
||||||
unsigned EncPositionL:8;
|
|
||||||
unsigned EncVelH:8;
|
|
||||||
unsigned EncVelL:8;
|
|
||||||
unsigned EncIndexRiseEventsH:8;
|
|
||||||
unsigned EncIndexRiseEventsL:8;
|
|
||||||
unsigned reserved:3;
|
|
||||||
unsigned VelDiv4:1;
|
|
||||||
unsigned PosDiv8:1;
|
|
||||||
unsigned QuadIdxpin:1;
|
|
||||||
unsigned QuadBpin:1;
|
|
||||||
unsigned QuadApin:1;
|
|
||||||
} TALON_Status_3_Enc_100ms_t ;
|
|
||||||
typedef struct _TALON_Status_4_AinTempVbat_100ms_t {
|
|
||||||
unsigned AnalogInWithOvH:8;
|
|
||||||
unsigned AnalogInWithOvM:8;
|
|
||||||
unsigned AnalogInWithOvL:8;
|
|
||||||
unsigned AnalogInVelH:8;
|
|
||||||
unsigned AnalogInVelL:8;
|
|
||||||
unsigned Temp:8;
|
|
||||||
unsigned BatteryV:8;
|
|
||||||
unsigned reserved:6;
|
|
||||||
unsigned VelDiv4:1;
|
|
||||||
unsigned PosDiv8:1;
|
|
||||||
} TALON_Status_4_AinTempVbat_100ms_t ;
|
|
||||||
typedef struct _TALON_Status_5_Startup_OneShot_t {
|
|
||||||
unsigned ResetCountH:8;
|
|
||||||
unsigned ResetCountL:8;
|
|
||||||
unsigned ResetFlagsH:8;
|
|
||||||
unsigned ResetFlagsL:8;
|
|
||||||
unsigned FirmVersH:8;
|
|
||||||
unsigned FirmVersL:8;
|
|
||||||
} TALON_Status_5_Startup_OneShot_t ;
|
|
||||||
typedef struct _TALON_Status_6_Eol_t {
|
|
||||||
unsigned currentAdcUncal_h2:2;
|
|
||||||
unsigned reserved1:5;
|
|
||||||
unsigned SpiCsPin_GadgeteerPin6:1;
|
|
||||||
unsigned currentAdcUncal_l8:8;
|
|
||||||
unsigned tempAdcUncal_h2:2;
|
|
||||||
unsigned reserved2:6;
|
|
||||||
unsigned tempAdcUncal_l8:8;
|
|
||||||
unsigned vbatAdcUncal_h2:2;
|
|
||||||
unsigned reserved3:6;
|
|
||||||
unsigned vbatAdcUncal_l8:8;
|
|
||||||
unsigned analogAdcUncal_h2:2;
|
|
||||||
unsigned reserved4:6;
|
|
||||||
unsigned analogAdcUncal_l8:8;
|
|
||||||
} TALON_Status_6_Eol_t ;
|
|
||||||
typedef struct _TALON_Status_7_Debug_200ms_t {
|
|
||||||
unsigned TokenizationFails_h8:8;
|
|
||||||
unsigned TokenizationFails_l8:8;
|
|
||||||
unsigned LastFailedToken_h8:8;
|
|
||||||
unsigned LastFailedToken_l8:8;
|
|
||||||
unsigned TokenizationSucceses_h8:8;
|
|
||||||
unsigned TokenizationSucceses_l8:8;
|
|
||||||
} TALON_Status_7_Debug_200ms_t ;
|
|
||||||
typedef struct _TALON_Status_8_PulseWid_100ms_t {
|
|
||||||
unsigned PulseWidPositionH:8;
|
|
||||||
unsigned PulseWidPositionM:8;
|
|
||||||
unsigned PulseWidPositionL:8;
|
|
||||||
unsigned reserved:6;
|
|
||||||
unsigned VelDiv4:1;
|
|
||||||
unsigned PosDiv8:1;
|
|
||||||
unsigned PeriodUsM8:8;
|
|
||||||
unsigned PeriodUsL8:8;
|
|
||||||
unsigned PulseWidVelH:8;
|
|
||||||
unsigned PulseWidVelL:8;
|
|
||||||
} TALON_Status_8_PulseWid_100ms_t ;
|
|
||||||
typedef struct _TALON_Status_9_MotProfBuffer_100ms_t {
|
|
||||||
unsigned ActTraj_IsValid:1; //!< '1' if other ActTraj_* signals are valid. '0' if there is no active trajectory pt.
|
|
||||||
unsigned ActTraj_ProfileSlotSelect:1;
|
|
||||||
unsigned ActTraj_VelOnly:1;
|
|
||||||
unsigned ActTraj_IsLast:1;
|
|
||||||
unsigned OutputType:2;
|
|
||||||
unsigned HasUnderrun:1;
|
|
||||||
unsigned IsUnderrun:1;
|
|
||||||
unsigned NextID:4;
|
|
||||||
unsigned reserved1:3;
|
|
||||||
unsigned BufferIsFull:1;
|
|
||||||
unsigned Count:8;
|
|
||||||
unsigned ActTraj_VelocityH:8;
|
|
||||||
unsigned ActTraj_VelocityL:8;
|
|
||||||
unsigned ActTraj_PositionH:8;
|
|
||||||
unsigned ActTraj_PositionM:8;
|
|
||||||
unsigned ActTraj_PositionL:8;
|
|
||||||
} TALON_Status_9_MotProfBuffer_100ms_t ;
|
|
||||||
typedef struct _TALON_Param_Request_t {
|
|
||||||
unsigned ParamEnum:8;
|
|
||||||
} TALON_Param_Request_t ;
|
|
||||||
typedef struct _TALON_Param_Response_t {
|
|
||||||
unsigned ParamEnum:8;
|
|
||||||
unsigned ParamValueL:8;
|
|
||||||
unsigned ParamValueML:8;
|
|
||||||
unsigned ParamValueMH:8;
|
|
||||||
unsigned ParamValueH:8;
|
|
||||||
} TALON_Param_Response_t ;
|
|
||||||
|
|
||||||
#endif /* CTRE_FRAMES_H */
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* Copyright (c) FIRST 2008-2016. All Rights Reserved. */
|
|
||||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
||||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
||||||
/* the project. */
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
||||||
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
|
|
||||||
|
|
||||||
#include "FRC_FPGA_ChipObject/tDMAChannelDescriptor.h" // NOLINT
|
|
||||||
#include "FRC_FPGA_ChipObject/tDMAManager.h" // NOLINT
|
|
||||||
#include "FRC_FPGA_ChipObject/tInterruptManager.h" // NOLINT
|
|
||||||
#include "FRC_FPGA_ChipObject/tSystem.h" // NOLINT
|
|
||||||
#include "FRC_FPGA_ChipObject/tSystemInterface.h" // NOLINT
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "FRC_FPGA_ChipObject/RoboRIO_FRC_ChipObject_Aliases.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/nInterfaceGlobals.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAI.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAO.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccel.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccumulator.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAlarm.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAnalogTrigger.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tBIST.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tCounter.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tDIO.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tDMA.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tEncoder.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tGlobal.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tInterrupt.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPWM.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPower.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tRelay.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSPI.h"
|
|
||||||
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSysWatchdog.h"
|
|
||||||
|
|
||||||
// FIXME: these should not be here!
|
|
||||||
using namespace nFPGA;
|
|
||||||
using namespace nRoboRIO_FPGANamespace;
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// Copyright (c) National Instruments 2008. All Rights Reserved.
|
|
||||||
// Do Not Edit... this file is generated!
|
|
||||||
|
|
||||||
#ifndef __nFRC_2017_17_0_2_nInterfaceGlobals_h__
|
|
||||||
#define __nFRC_2017_17_0_2_nInterfaceGlobals_h__
|
|
||||||
|
|
||||||
namespace nFPGA
|
|
||||||
{
|
|
||||||
namespace nFRC_2017_17_0_2
|
|
||||||
{
|
|
||||||
extern unsigned int g_currentTargetClass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __nFRC_2017_17_0_2_nInterfaceGlobals_h__
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
// Copyright (c) National Instruments 2008. All Rights Reserved.
|
|
||||||
// Do Not Edit... this file is generated!
|
|
||||||
|
|
||||||
#ifndef __nFRC_2017_17_0_2_SPI_h__
|
|
||||||
#define __nFRC_2017_17_0_2_SPI_h__
|
|
||||||
|
|
||||||
#include "tSystemInterface.h"
|
|
||||||
|
|
||||||
namespace nFPGA
|
|
||||||
{
|
|
||||||
namespace nFRC_2017_17_0_2
|
|
||||||
{
|
|
||||||
|
|
||||||
class tSPI
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
tSPI(){}
|
|
||||||
virtual ~tSPI(){}
|
|
||||||
|
|
||||||
virtual tSystemInterface* getSystemInterface() = 0;
|
|
||||||
static tSPI* create(tRioStatusCode *status);
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
kNumSystems = 1,
|
|
||||||
} tIfaceConstants;
|
|
||||||
|
|
||||||
typedef
|
|
||||||
union{
|
|
||||||
struct{
|
|
||||||
#ifdef __vxworks
|
|
||||||
unsigned Hdr : 4;
|
|
||||||
unsigned MXP : 1;
|
|
||||||
#else
|
|
||||||
unsigned MXP : 1;
|
|
||||||
unsigned Hdr : 4;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
struct{
|
|
||||||
unsigned value : 5;
|
|
||||||
};
|
|
||||||
} tChipSelectActiveHigh;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
} tEnableDIO_IfaceConstants;
|
|
||||||
|
|
||||||
virtual void writeEnableDIO(unsigned char value, tRioStatusCode *status) = 0;
|
|
||||||
virtual unsigned char readEnableDIO(tRioStatusCode *status) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
} tChipSelectActiveHigh_IfaceConstants;
|
|
||||||
|
|
||||||
virtual void writeChipSelectActiveHigh(tChipSelectActiveHigh value, tRioStatusCode *status) = 0;
|
|
||||||
virtual void writeChipSelectActiveHigh_Hdr(unsigned char value, tRioStatusCode *status) = 0;
|
|
||||||
virtual void writeChipSelectActiveHigh_MXP(unsigned char value, tRioStatusCode *status) = 0;
|
|
||||||
virtual tChipSelectActiveHigh readChipSelectActiveHigh(tRioStatusCode *status) = 0;
|
|
||||||
virtual unsigned char readChipSelectActiveHigh_Hdr(tRioStatusCode *status) = 0;
|
|
||||||
virtual unsigned char readChipSelectActiveHigh_MXP(tRioStatusCode *status) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
tSPI(const tSPI&);
|
|
||||||
void operator=(const tSPI&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __nFRC_2017_17_0_2_SPI_h__
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user