Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/tuple.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 namespace base {
     11 
     12 namespace {
     13 
     14 void DoAdd(int a, int b, int c, int* res) {
     15   *res = a + b + c;
     16 }
     17 
     18 struct Addy {
     19   Addy() = default;
     20   void DoAdd(int a, int b, int c, int d, int* res) {
     21     *res = a + b + c + d;
     22   }
     23 };
     24 
     25 struct Addz {
     26   Addz() = default;
     27   void DoAdd(int a, int b, int c, int d, int e, int* res) {
     28     *res = a + b + c + d + e;
     29   }
     30 };
     31 
     32 }  // namespace
     33 
     34 TEST(TupleTest, Basic) {
     35   std::tuple<> t0 = std::make_tuple();
     36   ALLOW_UNUSED_LOCAL(t0);
     37   std::tuple<int> t1(1);
     38   std::tuple<int, const char*> t2 =
     39       std::make_tuple(1, static_cast<const char*>("wee"));
     40   ALLOW_UNUSED_LOCAL(t2);
     41   std::tuple<int, int, int> t3(1, 2, 3);
     42   ALLOW_UNUSED_LOCAL(t3);
     43   std::tuple<int, int, int, int*> t4(1, 2, 3, &std::get<0>(t1));
     44   std::tuple<int, int, int, int, int*> t5(1, 2, 3, 4, &std::get<0>(t4));
     45   std::tuple<int, int, int, int, int, int*> t6(1, 2, 3, 4, 5, &std::get<0>(t4));
     46 
     47   EXPECT_EQ(1, std::get<0>(t1));
     48   DispatchToFunction(&DoAdd, t4);
     49   EXPECT_EQ(6, std::get<0>(t1));
     50 
     51   int res = 0;
     52   DispatchToFunction(&DoAdd, std::make_tuple(9, 8, 7, &res));
     53   EXPECT_EQ(24, res);
     54 
     55   Addy addy;
     56   EXPECT_EQ(1, std::get<0>(t4));
     57   DispatchToMethod(&addy, &Addy::DoAdd, t5);
     58   EXPECT_EQ(10, std::get<0>(t4));
     59 
     60   Addz addz;
     61   EXPECT_EQ(10, std::get<0>(t4));
     62   DispatchToMethod(&addz, &Addz::DoAdd, t6);
     63   EXPECT_EQ(15, std::get<0>(t4));
     64 }
     65 
     66 namespace {
     67 
     68 struct CopyLogger {
     69   CopyLogger() { ++TimesConstructed; }
     70   CopyLogger(const CopyLogger& tocopy) { ++TimesConstructed; ++TimesCopied; }
     71   ~CopyLogger() = default;
     72 
     73   static int TimesCopied;
     74   static int TimesConstructed;
     75 };
     76 
     77 void SomeLoggerMethRef(const CopyLogger& logy, const CopyLogger* ptr, bool* b) {
     78   *b = &logy == ptr;
     79 }
     80 
     81 void SomeLoggerMethCopy(CopyLogger logy, const CopyLogger* ptr, bool* b) {
     82   *b = &logy == ptr;
     83 }
     84 
     85 int CopyLogger::TimesCopied = 0;
     86 int CopyLogger::TimesConstructed = 0;
     87 
     88 }  // namespace
     89 
     90 TEST(TupleTest, Copying) {
     91   CopyLogger logger;
     92   EXPECT_EQ(0, CopyLogger::TimesCopied);
     93   EXPECT_EQ(1, CopyLogger::TimesConstructed);
     94 
     95   bool res = false;
     96 
     97   // Creating the tuple should copy the class to store internally in the tuple.
     98   std::tuple<CopyLogger, CopyLogger*, bool*> tuple(logger, &logger, &res);
     99   std::get<CopyLogger*>(tuple) = &std::get<CopyLogger>(tuple);
    100   EXPECT_EQ(2, CopyLogger::TimesConstructed);
    101   EXPECT_EQ(1, CopyLogger::TimesCopied);
    102 
    103   // Our internal Logger and the one passed to the function should be the same.
    104   res = false;
    105   DispatchToFunction(&SomeLoggerMethRef, tuple);
    106   EXPECT_TRUE(res);
    107   EXPECT_EQ(2, CopyLogger::TimesConstructed);
    108   EXPECT_EQ(1, CopyLogger::TimesCopied);
    109 
    110   // Now they should be different, since the function call will make a copy.
    111   res = false;
    112   DispatchToFunction(&SomeLoggerMethCopy, tuple);
    113   EXPECT_FALSE(res);
    114   EXPECT_EQ(3, CopyLogger::TimesConstructed);
    115   EXPECT_EQ(2, CopyLogger::TimesCopied);
    116 }
    117 
    118 }  // namespace base
    119