00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "gmock/gmock-generated-actions.h"
00037
00038 #include <functional>
00039 #include <sstream>
00040 #include <string>
00041 #include "gmock/gmock.h"
00042 #include "gtest/gtest.h"
00043
00044 namespace testing {
00045 namespace gmock_generated_actions_test {
00046
00047 using ::std::plus;
00048 using ::std::string;
00049 using ::std::tr1::get;
00050 using ::std::tr1::make_tuple;
00051 using ::std::tr1::tuple;
00052 using ::std::tr1::tuple_element;
00053 using testing::_;
00054 using testing::Action;
00055 using testing::ActionInterface;
00056 using testing::ByRef;
00057 using testing::DoAll;
00058 using testing::Invoke;
00059 using testing::Return;
00060 using testing::ReturnNew;
00061 using testing::SetArgPointee;
00062 using testing::StaticAssertTypeEq;
00063 using testing::Unused;
00064 using testing::WithArgs;
00065
00066
00067 inline short Short(short n) { return n; }
00068 inline char Char(char ch) { return ch; }
00069
00070
00071 int Nullary() { return 1; }
00072
00073 class NullaryFunctor {
00074 public:
00075 int operator()() { return 2; }
00076 };
00077
00078 bool g_done = false;
00079
00080 bool Unary(int x) { return x < 0; }
00081
00082 const char* Plus1(const char* s) { return s + 1; }
00083
00084 bool ByConstRef(const string& s) { return s == "Hi"; }
00085
00086 const double g_double = 0;
00087 bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
00088
00089 string ByNonConstRef(string& s) { return s += "+"; }
00090
00091 struct UnaryFunctor {
00092 int operator()(bool x) { return x ? 1 : -1; }
00093 };
00094
00095 const char* Binary(const char* input, short n) { return input + n; }
00096
00097 void VoidBinary(int, char) { g_done = true; }
00098
00099 int Ternary(int x, char y, short z) { return x + y + z; }
00100
00101 void VoidTernary(int, char, bool) { g_done = true; }
00102
00103 int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
00104
00105 string Concat4(const char* s1, const char* s2, const char* s3,
00106 const char* s4) {
00107 return string(s1) + s2 + s3 + s4;
00108 }
00109
00110 int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
00111
00112 struct SumOf5Functor {
00113 int operator()(int a, int b, int c, int d, int e) {
00114 return a + b + c + d + e;
00115 }
00116 };
00117
00118 string Concat5(const char* s1, const char* s2, const char* s3,
00119 const char* s4, const char* s5) {
00120 return string(s1) + s2 + s3 + s4 + s5;
00121 }
00122
00123 int SumOf6(int a, int b, int c, int d, int e, int f) {
00124 return a + b + c + d + e + f;
00125 }
00126
00127 struct SumOf6Functor {
00128 int operator()(int a, int b, int c, int d, int e, int f) {
00129 return a + b + c + d + e + f;
00130 }
00131 };
00132
00133 string Concat6(const char* s1, const char* s2, const char* s3,
00134 const char* s4, const char* s5, const char* s6) {
00135 return string(s1) + s2 + s3 + s4 + s5 + s6;
00136 }
00137
00138 string Concat7(const char* s1, const char* s2, const char* s3,
00139 const char* s4, const char* s5, const char* s6,
00140 const char* s7) {
00141 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
00142 }
00143
00144 string Concat8(const char* s1, const char* s2, const char* s3,
00145 const char* s4, const char* s5, const char* s6,
00146 const char* s7, const char* s8) {
00147 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
00148 }
00149
00150 string Concat9(const char* s1, const char* s2, const char* s3,
00151 const char* s4, const char* s5, const char* s6,
00152 const char* s7, const char* s8, const char* s9) {
00153 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
00154 }
00155
00156 string Concat10(const char* s1, const char* s2, const char* s3,
00157 const char* s4, const char* s5, const char* s6,
00158 const char* s7, const char* s8, const char* s9,
00159 const char* s10) {
00160 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
00161 }
00162
00163
00164
00165 inline const char* CharPtr(const char* s) { return s; }
00166
00167
00168
00169
00170 TEST(InvokeArgumentTest, Function0) {
00171 Action<int(int, int(*)())> a = InvokeArgument<1>();
00172 EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary)));
00173 }
00174
00175
00176 TEST(InvokeArgumentTest, Functor1) {
00177 Action<int(UnaryFunctor)> a = InvokeArgument<0>(true);
00178 EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor())));
00179 }
00180
00181
00182 TEST(InvokeArgumentTest, Function5) {
00183 Action<int(int(*)(int, int, int, int, int))> a =
00184 InvokeArgument<0>(10000, 2000, 300, 40, 5);
00185 EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5)));
00186 }
00187
00188
00189 TEST(InvokeArgumentTest, Functor5) {
00190 Action<int(SumOf5Functor)> a =
00191 InvokeArgument<0>(10000, 2000, 300, 40, 5);
00192 EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor())));
00193 }
00194
00195
00196 TEST(InvokeArgumentTest, Function6) {
00197 Action<int(int(*)(int, int, int, int, int, int))> a =
00198 InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
00199 EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6)));
00200 }
00201
00202
00203 TEST(InvokeArgumentTest, Functor6) {
00204 Action<int(SumOf6Functor)> a =
00205 InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
00206 EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor())));
00207 }
00208
00209
00210 TEST(InvokeArgumentTest, Function7) {
00211 Action<string(string(*)(const char*, const char*, const char*,
00212 const char*, const char*, const char*,
00213 const char*))> a =
00214 InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
00215 EXPECT_EQ("1234567", a.Perform(make_tuple(&Concat7)));
00216 }
00217
00218
00219 TEST(InvokeArgumentTest, Function8) {
00220 Action<string(string(*)(const char*, const char*, const char*,
00221 const char*, const char*, const char*,
00222 const char*, const char*))> a =
00223 InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
00224 EXPECT_EQ("12345678", a.Perform(make_tuple(&Concat8)));
00225 }
00226
00227
00228 TEST(InvokeArgumentTest, Function9) {
00229 Action<string(string(*)(const char*, const char*, const char*,
00230 const char*, const char*, const char*,
00231 const char*, const char*, const char*))> a =
00232 InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
00233 EXPECT_EQ("123456789", a.Perform(make_tuple(&Concat9)));
00234 }
00235
00236
00237 TEST(InvokeArgumentTest, Function10) {
00238 Action<string(string(*)(const char*, const char*, const char*,
00239 const char*, const char*, const char*,
00240 const char*, const char*, const char*,
00241 const char*))> a =
00242 InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
00243 EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10)));
00244 }
00245
00246
00247 TEST(InvokeArgumentTest, ByPointerFunction) {
00248 Action<const char*(const char*(*)(const char* input, short n))> a =
00249 InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));
00250 EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
00251 }
00252
00253
00254
00255 TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
00256 Action<const char*(const char*(*)(const char* input, short n))> a =
00257 InvokeArgument<0>("Hi", Short(1));
00258 EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
00259 }
00260
00261
00262 TEST(InvokeArgumentTest, ByConstReferenceFunction) {
00263 Action<bool(bool(*function)(const string& s))> a =
00264 InvokeArgument<0>(string("Hi"));
00265
00266
00267
00268 EXPECT_TRUE(a.Perform(make_tuple(&ByConstRef)));
00269 }
00270
00271
00272
00273 TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
00274 Action<bool(bool(*)(const double& x))> a =
00275 InvokeArgument<0>(ByRef(g_double));
00276
00277 EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
00278
00279 double x = 0;
00280 a = InvokeArgument<0>(ByRef(x));
00281 EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
00282 }
00283
00284
00285 TEST(WithArgsTest, OneArg) {
00286 Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary));
00287 EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
00288 EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
00289 }
00290
00291
00292 TEST(WithArgsTest, TwoArgs) {
00293 Action<const char*(const char* s, double x, short n)> a =
00294 WithArgs<0, 2>(Invoke(Binary));
00295 const char s[] = "Hello";
00296 EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, Short(2))));
00297 }
00298
00299
00300 TEST(WithArgsTest, ThreeArgs) {
00301 Action<int(int, double, char, short)> a =
00302 WithArgs<0, 2, 3>(Invoke(Ternary));
00303 EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, Char(20), Short(3))));
00304 }
00305
00306
00307 TEST(WithArgsTest, FourArgs) {
00308 Action<string(const char*, const char*, double, const char*, const char*)> a =
00309 WithArgs<4, 3, 1, 0>(Invoke(Concat4));
00310 EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5,
00311 CharPtr("3"), CharPtr("4"))));
00312 }
00313
00314
00315 TEST(WithArgsTest, FiveArgs) {
00316 Action<string(const char*, const char*, const char*,
00317 const char*, const char*)> a =
00318 WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5));
00319 EXPECT_EQ("43210",
00320 a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
00321 CharPtr("3"), CharPtr("4"))));
00322 }
00323
00324
00325 TEST(WithArgsTest, SixArgs) {
00326 Action<string(const char*, const char*, const char*)> a =
00327 WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6));
00328 EXPECT_EQ("012210",
00329 a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"))));
00330 }
00331
00332
00333 TEST(WithArgsTest, SevenArgs) {
00334 Action<string(const char*, const char*, const char*, const char*)> a =
00335 WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7));
00336 EXPECT_EQ("0123210",
00337 a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
00338 CharPtr("3"))));
00339 }
00340
00341
00342 TEST(WithArgsTest, EightArgs) {
00343 Action<string(const char*, const char*, const char*, const char*)> a =
00344 WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8));
00345 EXPECT_EQ("01230123",
00346 a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
00347 CharPtr("3"))));
00348 }
00349
00350
00351 TEST(WithArgsTest, NineArgs) {
00352 Action<string(const char*, const char*, const char*, const char*)> a =
00353 WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9));
00354 EXPECT_EQ("012312323",
00355 a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
00356 CharPtr("3"))));
00357 }
00358
00359
00360 TEST(WithArgsTest, TenArgs) {
00361 Action<string(const char*, const char*, const char*, const char*)> a =
00362 WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10));
00363 EXPECT_EQ("0123210123",
00364 a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
00365 CharPtr("3"))));
00366 }
00367
00368
00369 class SubstractAction : public ActionInterface<int(int, int)> {
00370 public:
00371 virtual int Perform(const tuple<int, int>& args) {
00372 return get<0>(args) - get<1>(args);
00373 }
00374 };
00375
00376 TEST(WithArgsTest, NonInvokeAction) {
00377 Action<int(const string&, int, int)> a =
00378 WithArgs<2, 1>(MakeAction(new SubstractAction));
00379 EXPECT_EQ(8, a.Perform(make_tuple(string("hi"), 2, 10)));
00380 }
00381
00382
00383 TEST(WithArgsTest, Identity) {
00384 Action<int(int x, char y, short z)> a =
00385 WithArgs<0, 1, 2>(Invoke(Ternary));
00386 EXPECT_EQ(123, a.Perform(make_tuple(100, Char(20), Short(3))));
00387 }
00388
00389
00390 TEST(WithArgsTest, RepeatedArguments) {
00391 Action<int(bool, int m, int n)> a =
00392 WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
00393 EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10)));
00394 }
00395
00396
00397 TEST(WithArgsTest, ReversedArgumentOrder) {
00398 Action<const char*(short n, const char* input)> a =
00399 WithArgs<1, 0>(Invoke(Binary));
00400 const char s[] = "Hello";
00401 EXPECT_EQ(s + 2, a.Perform(make_tuple(Short(2), CharPtr(s))));
00402 }
00403
00404
00405 TEST(WithArgsTest, ArgsOfCompatibleTypes) {
00406 Action<long(short x, char y, double z, char c)> a =
00407 WithArgs<0, 1, 3>(Invoke(Ternary));
00408 EXPECT_EQ(123, a.Perform(make_tuple(Short(100), Char(20), 5.6, Char(3))));
00409 }
00410
00411
00412 TEST(WithArgsTest, VoidAction) {
00413 Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
00414 g_done = false;
00415 a.Perform(make_tuple(1.5, 'a', 3));
00416 EXPECT_TRUE(g_done);
00417 }
00418
00419
00420 TEST(DoAllTest, TwoActions) {
00421 int n = 0;
00422 Action<int(int*)> a = DoAll(SetArgPointee<0>(1),
00423 Return(2));
00424 EXPECT_EQ(2, a.Perform(make_tuple(&n)));
00425 EXPECT_EQ(1, n);
00426 }
00427
00428
00429 TEST(DoAllTest, ThreeActions) {
00430 int m = 0, n = 0;
00431 Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1),
00432 SetArgPointee<1>(2),
00433 Return(3));
00434 EXPECT_EQ(3, a.Perform(make_tuple(&m, &n)));
00435 EXPECT_EQ(1, m);
00436 EXPECT_EQ(2, n);
00437 }
00438
00439
00440 TEST(DoAllTest, FourActions) {
00441 int m = 0, n = 0;
00442 char ch = '\0';
00443 Action<int(int*, int*, char*)> a =
00444 DoAll(SetArgPointee<0>(1),
00445 SetArgPointee<1>(2),
00446 SetArgPointee<2>('a'),
00447 Return(3));
00448 EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch)));
00449 EXPECT_EQ(1, m);
00450 EXPECT_EQ(2, n);
00451 EXPECT_EQ('a', ch);
00452 }
00453
00454
00455 TEST(DoAllTest, FiveActions) {
00456 int m = 0, n = 0;
00457 char a = '\0', b = '\0';
00458 Action<int(int*, int*, char*, char*)> action =
00459 DoAll(SetArgPointee<0>(1),
00460 SetArgPointee<1>(2),
00461 SetArgPointee<2>('a'),
00462 SetArgPointee<3>('b'),
00463 Return(3));
00464 EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b)));
00465 EXPECT_EQ(1, m);
00466 EXPECT_EQ(2, n);
00467 EXPECT_EQ('a', a);
00468 EXPECT_EQ('b', b);
00469 }
00470
00471
00472 TEST(DoAllTest, SixActions) {
00473 int m = 0, n = 0;
00474 char a = '\0', b = '\0', c = '\0';
00475 Action<int(int*, int*, char*, char*, char*)> action =
00476 DoAll(SetArgPointee<0>(1),
00477 SetArgPointee<1>(2),
00478 SetArgPointee<2>('a'),
00479 SetArgPointee<3>('b'),
00480 SetArgPointee<4>('c'),
00481 Return(3));
00482 EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c)));
00483 EXPECT_EQ(1, m);
00484 EXPECT_EQ(2, n);
00485 EXPECT_EQ('a', a);
00486 EXPECT_EQ('b', b);
00487 EXPECT_EQ('c', c);
00488 }
00489
00490
00491 TEST(DoAllTest, SevenActions) {
00492 int m = 0, n = 0;
00493 char a = '\0', b = '\0', c = '\0', d = '\0';
00494 Action<int(int*, int*, char*, char*, char*, char*)> action =
00495 DoAll(SetArgPointee<0>(1),
00496 SetArgPointee<1>(2),
00497 SetArgPointee<2>('a'),
00498 SetArgPointee<3>('b'),
00499 SetArgPointee<4>('c'),
00500 SetArgPointee<5>('d'),
00501 Return(3));
00502 EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d)));
00503 EXPECT_EQ(1, m);
00504 EXPECT_EQ(2, n);
00505 EXPECT_EQ('a', a);
00506 EXPECT_EQ('b', b);
00507 EXPECT_EQ('c', c);
00508 EXPECT_EQ('d', d);
00509 }
00510
00511
00512 TEST(DoAllTest, EightActions) {
00513 int m = 0, n = 0;
00514 char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
00515 Action<int(int*, int*, char*, char*, char*, char*,
00516 char*)> action =
00517 DoAll(SetArgPointee<0>(1),
00518 SetArgPointee<1>(2),
00519 SetArgPointee<2>('a'),
00520 SetArgPointee<3>('b'),
00521 SetArgPointee<4>('c'),
00522 SetArgPointee<5>('d'),
00523 SetArgPointee<6>('e'),
00524 Return(3));
00525 EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e)));
00526 EXPECT_EQ(1, m);
00527 EXPECT_EQ(2, n);
00528 EXPECT_EQ('a', a);
00529 EXPECT_EQ('b', b);
00530 EXPECT_EQ('c', c);
00531 EXPECT_EQ('d', d);
00532 EXPECT_EQ('e', e);
00533 }
00534
00535
00536 TEST(DoAllTest, NineActions) {
00537 int m = 0, n = 0;
00538 char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
00539 Action<int(int*, int*, char*, char*, char*, char*,
00540 char*, char*)> action =
00541 DoAll(SetArgPointee<0>(1),
00542 SetArgPointee<1>(2),
00543 SetArgPointee<2>('a'),
00544 SetArgPointee<3>('b'),
00545 SetArgPointee<4>('c'),
00546 SetArgPointee<5>('d'),
00547 SetArgPointee<6>('e'),
00548 SetArgPointee<7>('f'),
00549 Return(3));
00550 EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
00551 EXPECT_EQ(1, m);
00552 EXPECT_EQ(2, n);
00553 EXPECT_EQ('a', a);
00554 EXPECT_EQ('b', b);
00555 EXPECT_EQ('c', c);
00556 EXPECT_EQ('d', d);
00557 EXPECT_EQ('e', e);
00558 EXPECT_EQ('f', f);
00559 }
00560
00561
00562 TEST(DoAllTest, TenActions) {
00563 int m = 0, n = 0;
00564 char a = '\0', b = '\0', c = '\0', d = '\0';
00565 char e = '\0', f = '\0', g = '\0';
00566 Action<int(int*, int*, char*, char*, char*, char*,
00567 char*, char*, char*)> action =
00568 DoAll(SetArgPointee<0>(1),
00569 SetArgPointee<1>(2),
00570 SetArgPointee<2>('a'),
00571 SetArgPointee<3>('b'),
00572 SetArgPointee<4>('c'),
00573 SetArgPointee<5>('d'),
00574 SetArgPointee<6>('e'),
00575 SetArgPointee<7>('f'),
00576 SetArgPointee<8>('g'),
00577 Return(3));
00578 EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
00579 EXPECT_EQ(1, m);
00580 EXPECT_EQ(2, n);
00581 EXPECT_EQ('a', a);
00582 EXPECT_EQ('b', b);
00583 EXPECT_EQ('c', c);
00584 EXPECT_EQ('d', d);
00585 EXPECT_EQ('e', e);
00586 EXPECT_EQ('f', f);
00587 EXPECT_EQ('g', g);
00588 }
00589
00590
00591
00592
00593
00594
00595 #ifdef _MSC_VER
00596 # pragma warning(push)
00597 # pragma warning(disable:4100)
00598 #endif
00599
00600
00601
00602
00603
00604 ACTION(Return5) { return 5; }
00605
00606 TEST(ActionMacroTest, WorksWhenNotReferencingArguments) {
00607 Action<double()> a1 = Return5();
00608 EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple()));
00609
00610 Action<int(double, bool)> a2 = Return5();
00611 EXPECT_EQ(5, a2.Perform(make_tuple(1, true)));
00612 }
00613
00614
00615 ACTION(IncrementArg1) { (*arg1)++; }
00616
00617 TEST(ActionMacroTest, WorksWhenReturningVoid) {
00618 Action<void(int, int*)> a1 = IncrementArg1();
00619 int n = 0;
00620 a1.Perform(make_tuple(5, &n));
00621 EXPECT_EQ(1, n);
00622 }
00623
00624
00625
00626 ACTION(IncrementArg2) {
00627 StaticAssertTypeEq<int*, arg2_type>();
00628 arg2_type temp = arg2;
00629 (*temp)++;
00630 }
00631
00632 TEST(ActionMacroTest, CanReferenceArgumentType) {
00633 Action<void(int, bool, int*)> a1 = IncrementArg2();
00634 int n = 0;
00635 a1.Perform(make_tuple(5, false, &n));
00636 EXPECT_EQ(1, n);
00637 }
00638
00639
00640
00641 ACTION(Sum2) {
00642 StaticAssertTypeEq< ::std::tr1::tuple<int, char, int*>, args_type>();
00643 args_type args_copy = args;
00644 return get<0>(args_copy) + get<1>(args_copy);
00645 }
00646
00647 TEST(ActionMacroTest, CanReferenceArgumentTuple) {
00648 Action<int(int, char, int*)> a1 = Sum2();
00649 int dummy = 0;
00650 EXPECT_EQ(11, a1.Perform(make_tuple(5, Char(6), &dummy)));
00651 }
00652
00653
00654
00655 int Dummy(bool flag) { return flag? 1 : 0; }
00656
00657 ACTION(InvokeDummy) {
00658 StaticAssertTypeEq<int(bool), function_type>();
00659 function_type* fp = &Dummy;
00660 return (*fp)(true);
00661 }
00662
00663 TEST(ActionMacroTest, CanReferenceMockFunctionType) {
00664 Action<int(bool)> a1 = InvokeDummy();
00665 EXPECT_EQ(1, a1.Perform(make_tuple(true)));
00666 EXPECT_EQ(1, a1.Perform(make_tuple(false)));
00667 }
00668
00669
00670
00671 ACTION(InvokeDummy2) {
00672 StaticAssertTypeEq<int, return_type>();
00673 return_type result = Dummy(true);
00674 return result;
00675 }
00676
00677 TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {
00678 Action<int(bool)> a1 = InvokeDummy2();
00679 EXPECT_EQ(1, a1.Perform(make_tuple(true)));
00680 EXPECT_EQ(1, a1.Perform(make_tuple(false)));
00681 }
00682
00683
00684 ACTION(ReturnAddrOfConstBoolReferenceArg) {
00685 StaticAssertTypeEq<const bool&, arg1_type>();
00686 return &arg1;
00687 }
00688
00689 TEST(ActionMacroTest, WorksForConstReferenceArg) {
00690 Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();
00691 const bool b = false;
00692 EXPECT_EQ(&b, a.Perform(tuple<int, const bool&>(0, b)));
00693 }
00694
00695
00696 ACTION(ReturnAddrOfIntReferenceArg) {
00697 StaticAssertTypeEq<int&, arg0_type>();
00698 return &arg0;
00699 }
00700
00701 TEST(ActionMacroTest, WorksForNonConstReferenceArg) {
00702 Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();
00703 int n = 0;
00704 EXPECT_EQ(&n, a.Perform(tuple<int&, bool, int>(n, true, 1)));
00705 }
00706
00707
00708 namespace action_test {
00709 ACTION(Sum) { return arg0 + arg1; }
00710 }
00711
00712 TEST(ActionMacroTest, WorksInNamespace) {
00713 Action<int(int, int)> a1 = action_test::Sum();
00714 EXPECT_EQ(3, a1.Perform(make_tuple(1, 2)));
00715 }
00716
00717
00718
00719 ACTION(PlusTwo) { return arg0 + 2; }
00720
00721 TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {
00722 Action<int(int)> a1 = PlusTwo();
00723 EXPECT_EQ(4, a1.Perform(make_tuple(2)));
00724
00725 Action<double(float, void*)> a2 = PlusTwo();
00726 int dummy;
00727 EXPECT_DOUBLE_EQ(6, a2.Perform(make_tuple(4.0f, &dummy)));
00728 }
00729
00730
00731 ACTION_P(Plus, n) { return arg0 + n; }
00732
00733 TEST(ActionPMacroTest, DefinesParameterizedAction) {
00734 Action<int(int m, bool t)> a1 = Plus(9);
00735 EXPECT_EQ(10, a1.Perform(make_tuple(1, true)));
00736 }
00737
00738
00739
00740 ACTION_P(TypedPlus, n) {
00741 arg0_type t1 = arg0;
00742 n_type t2 = n;
00743 return t1 + t2;
00744 }
00745
00746 TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {
00747 Action<int(char m, bool t)> a1 = TypedPlus(9);
00748 EXPECT_EQ(10, a1.Perform(make_tuple(Char(1), true)));
00749 }
00750
00751
00752
00753 TEST(ActionPMacroTest, WorksInCompatibleMockFunction) {
00754 Action<std::string(const std::string& s)> a1 = Plus("tail");
00755 const std::string re = "re";
00756 EXPECT_EQ("retail", a1.Perform(make_tuple(re)));
00757 }
00758
00759
00760
00761
00762 ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }
00763
00764 ACTION_P(OverloadedAction, default_value) {
00765 return arg0 ? arg1 : default_value;
00766 }
00767
00768 ACTION_P2(OverloadedAction, true_value, false_value) {
00769 return arg0 ? true_value : false_value;
00770 }
00771
00772 TEST(ActionMacroTest, CanDefineOverloadedActions) {
00773 typedef Action<const char*(bool, const char*)> MyAction;
00774
00775 const MyAction a1 = OverloadedAction();
00776 EXPECT_STREQ("hello", a1.Perform(make_tuple(false, CharPtr("world"))));
00777 EXPECT_STREQ("world", a1.Perform(make_tuple(true, CharPtr("world"))));
00778
00779 const MyAction a2 = OverloadedAction("hi");
00780 EXPECT_STREQ("hi", a2.Perform(make_tuple(false, CharPtr("world"))));
00781 EXPECT_STREQ("world", a2.Perform(make_tuple(true, CharPtr("world"))));
00782
00783 const MyAction a3 = OverloadedAction("hi", "you");
00784 EXPECT_STREQ("hi", a3.Perform(make_tuple(true, CharPtr("world"))));
00785 EXPECT_STREQ("you", a3.Perform(make_tuple(false, CharPtr("world"))));
00786 }
00787
00788
00789
00790 ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }
00791
00792 TEST(ActionPnMacroTest, WorksFor3Parameters) {
00793 Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);
00794 EXPECT_DOUBLE_EQ(3123.4, a1.Perform(make_tuple(3000, true)));
00795
00796 Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");
00797 const std::string re = "re";
00798 EXPECT_EQ("retail->", a2.Perform(make_tuple(re)));
00799 }
00800
00801 ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }
00802
00803 TEST(ActionPnMacroTest, WorksFor4Parameters) {
00804 Action<int(int)> a1 = Plus(1, 2, 3, 4);
00805 EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(make_tuple(10)));
00806 }
00807
00808 ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }
00809
00810 TEST(ActionPnMacroTest, WorksFor5Parameters) {
00811 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);
00812 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(make_tuple(10)));
00813 }
00814
00815 ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {
00816 return arg0 + p0 + p1 + p2 + p3 + p4 + p5;
00817 }
00818
00819 TEST(ActionPnMacroTest, WorksFor6Parameters) {
00820 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);
00821 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(make_tuple(10)));
00822 }
00823
00824 ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {
00825 return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;
00826 }
00827
00828 TEST(ActionPnMacroTest, WorksFor7Parameters) {
00829 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);
00830 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(make_tuple(10)));
00831 }
00832
00833 ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {
00834 return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
00835 }
00836
00837 TEST(ActionPnMacroTest, WorksFor8Parameters) {
00838 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);
00839 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, a1.Perform(make_tuple(10)));
00840 }
00841
00842 ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {
00843 return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;
00844 }
00845
00846 TEST(ActionPnMacroTest, WorksFor9Parameters) {
00847 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);
00848 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, a1.Perform(make_tuple(10)));
00849 }
00850
00851 ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {
00852 arg0_type t0 = arg0;
00853 last_param_type t9 = last_param;
00854 return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;
00855 }
00856
00857 TEST(ActionPnMacroTest, WorksFor10Parameters) {
00858 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
00859 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,
00860 a1.Perform(make_tuple(10)));
00861 }
00862
00863
00864
00865 ACTION_P2(PadArgument, prefix, suffix) {
00866
00867 std::string prefix_str(prefix);
00868 char suffix_char = static_cast<char>(suffix);
00869 return prefix_str + arg0 + suffix_char;
00870 }
00871
00872 TEST(ActionPnMacroTest, SimpleTypePromotion) {
00873 Action<std::string(const char*)> no_promo =
00874 PadArgument(std::string("foo"), 'r');
00875 Action<std::string(const char*)> promo =
00876 PadArgument("foo", static_cast<int>('r'));
00877 EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba"))));
00878 EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba"))));
00879 }
00880
00881
00882
00883
00884
00885
00886 ACTION_P3(ConcatImpl, a, b, c) {
00887 std::stringstream ss;
00888 ss << a << b << c;
00889 return ss.str();
00890 }
00891
00892
00893
00894
00895
00896
00897 template <typename T1, typename T2>
00898
00899
00900
00901 ConcatImplActionP3<std::string, T1, T2>
00902 Concat(const std::string& a, T1 b, T2 c) {
00903 if (true) {
00904
00905
00906 return ConcatImpl(a, b, c);
00907 } else {
00908
00909
00910
00911 return ConcatImpl<std::string, T1, T2>(a, b, c);
00912 }
00913 }
00914
00915
00916
00917 template <typename T1, typename T2>
00918 ConcatImplActionP3<T1, int, T2>
00919 Concat(T1 a, int b, T2 c) {
00920 return ConcatImpl(a, b, c);
00921 }
00922
00923 TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {
00924 Action<const std::string()> a1 = Concat("Hello", "1", 2);
00925 EXPECT_EQ("Hello12", a1.Perform(make_tuple()));
00926
00927 a1 = Concat(1, 2, 3);
00928 EXPECT_EQ("123", a1.Perform(make_tuple()));
00929 }
00930
00931
00932
00933 ACTION(DoFoo) {}
00934 ACTION_P(DoFoo, p) {}
00935 ACTION_P2(DoFoo, p0, p1) {}
00936
00937 TEST(ActionPnMacroTest, TypesAreCorrect) {
00938
00939 DoFooAction a0 = DoFoo();
00940
00941
00942 DoFooActionP<int> a1 = DoFoo(1);
00943
00944
00945
00946 DoFooActionP2<int, char> a2 = DoFoo(1, '2');
00947 PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');
00948 PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');
00949 PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');
00950 PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');
00951 PlusActionP7<int, int, int, int, int, int, char> a7 =
00952 Plus(1, 2, 3, 4, 5, 6, '7');
00953 PlusActionP8<int, int, int, int, int, int, int, char> a8 =
00954 Plus(1, 2, 3, 4, 5, 6, 7, '8');
00955 PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =
00956 Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');
00957 PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =
00958 Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
00959
00960
00961 (void)a0;
00962 (void)a1;
00963 (void)a2;
00964 (void)a3;
00965 (void)a4;
00966 (void)a5;
00967 (void)a6;
00968 (void)a7;
00969 (void)a8;
00970 (void)a9;
00971 (void)a10;
00972 }
00973
00974
00975
00976
00977 ACTION_P(Plus1, x) { return x; }
00978 ACTION_P2(Plus2, x, y) { return x + y; }
00979 ACTION_P3(Plus3, x, y, z) { return x + y + z; }
00980 ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
00981 return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
00982 }
00983
00984 TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
00985 int x = 1, y = 2, z = 3;
00986 const tuple<> empty = make_tuple();
00987
00988 Action<int()> a = Plus1<int&>(x);
00989 EXPECT_EQ(1, a.Perform(empty));
00990
00991 a = Plus2<const int&, int&>(x, y);
00992 EXPECT_EQ(3, a.Perform(empty));
00993
00994 a = Plus3<int&, const int&, int&>(x, y, z);
00995 EXPECT_EQ(6, a.Perform(empty));
00996
00997 int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
00998 a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,
00999 int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7],
01000 n[8], n[9]);
01001 EXPECT_EQ(55, a.Perform(empty));
01002 }
01003
01004 class NullaryConstructorClass {
01005 public:
01006 NullaryConstructorClass() : value_(123) {}
01007 int value_;
01008 };
01009
01010
01011 TEST(ReturnNewTest, NoArgs) {
01012 Action<NullaryConstructorClass*()> a = ReturnNew<NullaryConstructorClass>();
01013 NullaryConstructorClass* c = a.Perform(make_tuple());
01014 EXPECT_EQ(123, c->value_);
01015 delete c;
01016 }
01017
01018 class UnaryConstructorClass {
01019 public:
01020 explicit UnaryConstructorClass(int value) : value_(value) {}
01021 int value_;
01022 };
01023
01024
01025 TEST(ReturnNewTest, Unary) {
01026 Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000);
01027 UnaryConstructorClass* c = a.Perform(make_tuple());
01028 EXPECT_EQ(4000, c->value_);
01029 delete c;
01030 }
01031
01032 TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) {
01033 Action<UnaryConstructorClass*(bool, int)> a =
01034 ReturnNew<UnaryConstructorClass>(4000);
01035 UnaryConstructorClass* c = a.Perform(make_tuple(false, 5));
01036 EXPECT_EQ(4000, c->value_);
01037 delete c;
01038 }
01039
01040 TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) {
01041 Action<const UnaryConstructorClass*()> a =
01042 ReturnNew<UnaryConstructorClass>(4000);
01043 const UnaryConstructorClass* c = a.Perform(make_tuple());
01044 EXPECT_EQ(4000, c->value_);
01045 delete c;
01046 }
01047
01048 class TenArgConstructorClass {
01049 public:
01050 TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5,
01051 int a6, int a7, int a8, int a9, int a10)
01052 : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {
01053 }
01054 int value_;
01055 };
01056
01057
01058 TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
01059 Action<TenArgConstructorClass*()> a =
01060 ReturnNew<TenArgConstructorClass>(1000000000, 200000000, 30000000,
01061 4000000, 500000, 60000,
01062 7000, 800, 90, 0);
01063 TenArgConstructorClass* c = a.Perform(make_tuple());
01064 EXPECT_EQ(1234567890, c->value_);
01065 delete c;
01066 }
01067
01068
01069 ACTION_TEMPLATE(CreateNew,
01070 HAS_1_TEMPLATE_PARAMS(typename, T),
01071 AND_0_VALUE_PARAMS()) {
01072 return new T;
01073 }
01074
01075 TEST(ActionTemplateTest, WorksWithoutValueParam) {
01076 const Action<int*()> a = CreateNew<int>();
01077 int* p = a.Perform(make_tuple());
01078 delete p;
01079 }
01080
01081
01082 ACTION_TEMPLATE(CreateNew,
01083 HAS_1_TEMPLATE_PARAMS(typename, T),
01084 AND_1_VALUE_PARAMS(a0)) {
01085 return new T(a0);
01086 }
01087
01088 TEST(ActionTemplateTest, WorksWithValueParams) {
01089 const Action<int*()> a = CreateNew<int>(42);
01090 int* p = a.Perform(make_tuple());
01091 EXPECT_EQ(42, *p);
01092 delete p;
01093 }
01094
01095
01096 ACTION_TEMPLATE(MyDeleteArg,
01097 HAS_1_TEMPLATE_PARAMS(int, k),
01098 AND_0_VALUE_PARAMS()) {
01099 delete std::tr1::get<k>(args);
01100 }
01101
01102
01103 class BoolResetter {
01104 public:
01105 explicit BoolResetter(bool* value) : value_(value) {}
01106 ~BoolResetter() { *value_ = false; }
01107 private:
01108 bool* value_;
01109 };
01110
01111 TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
01112 const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
01113 int n = 0;
01114 bool b = true;
01115 BoolResetter* resetter = new BoolResetter(&b);
01116 a.Perform(make_tuple(&n, resetter));
01117 EXPECT_FALSE(b);
01118 }
01119
01120
01121 ACTION_TEMPLATE(ReturnSmartPointer,
01122 HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,
01123 Pointer),
01124 AND_1_VALUE_PARAMS(pointee)) {
01125 return Pointer<pointee_type>(new pointee_type(pointee));
01126 }
01127
01128 TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {
01129 using ::testing::internal::linked_ptr;
01130 const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42);
01131 linked_ptr<int> p = a.Perform(make_tuple());
01132 EXPECT_EQ(42, *p);
01133 }
01134
01135
01136 template <typename T1, typename T2, typename T3, int k4, bool k5,
01137 unsigned int k6, typename T7, typename T8, typename T9>
01138 struct GiantTemplate {
01139 public:
01140 explicit GiantTemplate(int a_value) : value(a_value) {}
01141 int value;
01142 };
01143
01144 ACTION_TEMPLATE(ReturnGiant,
01145 HAS_10_TEMPLATE_PARAMS(
01146 typename, T1,
01147 typename, T2,
01148 typename, T3,
01149 int, k4,
01150 bool, k5,
01151 unsigned int, k6,
01152 class, T7,
01153 class, T8,
01154 class, T9,
01155 template <typename T> class, T10),
01156 AND_1_VALUE_PARAMS(value)) {
01157 return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);
01158 }
01159
01160 TEST(ActionTemplateTest, WorksFor10TemplateParameters) {
01161 using ::testing::internal::linked_ptr;
01162 typedef GiantTemplate<linked_ptr<int>, bool, double, 5,
01163 true, 6, char, unsigned, int> Giant;
01164 const Action<Giant()> a = ReturnGiant<
01165 int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42);
01166 Giant giant = a.Perform(make_tuple());
01167 EXPECT_EQ(42, giant.value);
01168 }
01169
01170
01171 ACTION_TEMPLATE(ReturnSum,
01172 HAS_1_TEMPLATE_PARAMS(typename, Number),
01173 AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {
01174 return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
01175 }
01176
01177 TEST(ActionTemplateTest, WorksFor10ValueParameters) {
01178 const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
01179 EXPECT_EQ(55, a.Perform(make_tuple()));
01180 }
01181
01182
01183
01184
01185 ACTION(ReturnSum) { return 0; }
01186
01187 ACTION_P(ReturnSum, x) { return x; }
01188
01189 ACTION_TEMPLATE(ReturnSum,
01190 HAS_1_TEMPLATE_PARAMS(typename, Number),
01191 AND_2_VALUE_PARAMS(v1, v2)) {
01192 return static_cast<Number>(v1) + v2;
01193 }
01194
01195 ACTION_TEMPLATE(ReturnSum,
01196 HAS_1_TEMPLATE_PARAMS(typename, Number),
01197 AND_3_VALUE_PARAMS(v1, v2, v3)) {
01198 return static_cast<Number>(v1) + v2 + v3;
01199 }
01200
01201 ACTION_TEMPLATE(ReturnSum,
01202 HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),
01203 AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {
01204 return static_cast<Number>(v1) + v2 + v3 + v4 + k;
01205 }
01206
01207 TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
01208 const Action<int()> a0 = ReturnSum();
01209 const Action<int()> a1 = ReturnSum(1);
01210 const Action<int()> a2 = ReturnSum<int>(1, 2);
01211 const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
01212 const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
01213 EXPECT_EQ(0, a0.Perform(make_tuple()));
01214 EXPECT_EQ(1, a1.Perform(make_tuple()));
01215 EXPECT_EQ(3, a2.Perform(make_tuple()));
01216 EXPECT_EQ(6, a3.Perform(make_tuple()));
01217 EXPECT_EQ(12345, a4.Perform(make_tuple()));
01218 }
01219
01220 #ifdef _MSC_VER
01221 # pragma warning(pop)
01222 #endif
01223
01224 }
01225 }