michael@0: // Copyright 2007, Google Inc. michael@0: // All rights reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: // michael@0: // Author: wan@google.com (Zhanyong Wan) michael@0: michael@0: #include "gtest/internal/gtest-tuple.h" michael@0: #include michael@0: #include "gtest/gtest.h" michael@0: michael@0: namespace { michael@0: michael@0: using ::std::tr1::get; michael@0: using ::std::tr1::make_tuple; michael@0: using ::std::tr1::tuple; michael@0: using ::std::tr1::tuple_element; michael@0: using ::std::tr1::tuple_size; michael@0: using ::testing::StaticAssertTypeEq; michael@0: michael@0: // Tests that tuple_element >::type returns TK. michael@0: TEST(tuple_element_Test, ReturnsElementType) { michael@0: StaticAssertTypeEq >::type>(); michael@0: StaticAssertTypeEq >::type>(); michael@0: StaticAssertTypeEq >::type>(); michael@0: } michael@0: michael@0: // Tests that tuple_size::value gives the number of fields in tuple michael@0: // type T. michael@0: TEST(tuple_size_Test, ReturnsNumberOfFields) { michael@0: EXPECT_EQ(0, +tuple_size >::value); michael@0: EXPECT_EQ(1, +tuple_size >::value); michael@0: EXPECT_EQ(1, +tuple_size >::value); michael@0: EXPECT_EQ(1, +(tuple_size > >::value)); michael@0: EXPECT_EQ(2, +(tuple_size >::value)); michael@0: EXPECT_EQ(3, +(tuple_size >::value)); michael@0: } michael@0: michael@0: // Tests comparing a tuple with itself. michael@0: TEST(ComparisonTest, ComparesWithSelf) { michael@0: const tuple a(5, 'a', false); michael@0: michael@0: EXPECT_TRUE(a == a); michael@0: EXPECT_FALSE(a != a); michael@0: } michael@0: michael@0: // Tests comparing two tuples with the same value. michael@0: TEST(ComparisonTest, ComparesEqualTuples) { michael@0: const tuple a(5, true), b(5, true); michael@0: michael@0: EXPECT_TRUE(a == b); michael@0: EXPECT_FALSE(a != b); michael@0: } michael@0: michael@0: // Tests comparing two different tuples that have no reference fields. michael@0: TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) { michael@0: typedef tuple FooTuple; michael@0: michael@0: const FooTuple a(0, 'x'); michael@0: const FooTuple b(1, 'a'); michael@0: michael@0: EXPECT_TRUE(a != b); michael@0: EXPECT_FALSE(a == b); michael@0: michael@0: const FooTuple c(1, 'b'); michael@0: michael@0: EXPECT_TRUE(b != c); michael@0: EXPECT_FALSE(b == c); michael@0: } michael@0: michael@0: // Tests comparing two different tuples that have reference fields. michael@0: TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) { michael@0: typedef tuple FooTuple; michael@0: michael@0: int i = 5; michael@0: const char ch = 'a'; michael@0: const FooTuple a(i, ch); michael@0: michael@0: int j = 6; michael@0: const FooTuple b(j, ch); michael@0: michael@0: EXPECT_TRUE(a != b); michael@0: EXPECT_FALSE(a == b); michael@0: michael@0: j = 5; michael@0: const char ch2 = 'b'; michael@0: const FooTuple c(j, ch2); michael@0: michael@0: EXPECT_TRUE(b != c); michael@0: EXPECT_FALSE(b == c); michael@0: } michael@0: michael@0: // Tests that a tuple field with a reference type is an alias of the michael@0: // variable it's supposed to reference. michael@0: TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { michael@0: int n = 0; michael@0: tuple t(true, n); michael@0: michael@0: n = 1; michael@0: EXPECT_EQ(n, get<1>(t)) michael@0: << "Changing a underlying variable should update the reference field."; michael@0: michael@0: // Makes sure that the implementation doesn't do anything funny with michael@0: // the & operator for the return type of get<>(). michael@0: EXPECT_EQ(&n, &(get<1>(t))) michael@0: << "The address of a reference field should equal the address of " michael@0: << "the underlying variable."; michael@0: michael@0: get<1>(t) = 2; michael@0: EXPECT_EQ(2, n) michael@0: << "Changing a reference field should update the underlying variable."; michael@0: } michael@0: michael@0: // Tests that tuple's default constructor default initializes each field. michael@0: // This test needs to compile without generating warnings. michael@0: TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) { michael@0: // The TR1 report requires that tuple's default constructor default michael@0: // initializes each field, even if it's a primitive type. If the michael@0: // implementation forgets to do this, this test will catch it by michael@0: // generating warnings about using uninitialized variables (assuming michael@0: // a decent compiler). michael@0: michael@0: tuple<> empty; michael@0: michael@0: tuple a1, b1; michael@0: b1 = a1; michael@0: EXPECT_EQ(0, get<0>(b1)); michael@0: michael@0: tuple a2, b2; michael@0: b2 = a2; michael@0: EXPECT_EQ(0, get<0>(b2)); michael@0: EXPECT_EQ(0.0, get<1>(b2)); michael@0: michael@0: tuple a3, b3; michael@0: b3 = a3; michael@0: EXPECT_EQ(0.0, get<0>(b3)); michael@0: EXPECT_EQ('\0', get<1>(b3)); michael@0: EXPECT_TRUE(get<2>(b3) == NULL); michael@0: michael@0: tuple a10, b10; michael@0: b10 = a10; michael@0: EXPECT_EQ(0, get<0>(b10)); michael@0: EXPECT_EQ(0, get<1>(b10)); michael@0: EXPECT_EQ(0, get<2>(b10)); michael@0: EXPECT_EQ(0, get<3>(b10)); michael@0: EXPECT_EQ(0, get<4>(b10)); michael@0: EXPECT_EQ(0, get<5>(b10)); michael@0: EXPECT_EQ(0, get<6>(b10)); michael@0: EXPECT_EQ(0, get<7>(b10)); michael@0: EXPECT_EQ(0, get<8>(b10)); michael@0: EXPECT_EQ(0, get<9>(b10)); michael@0: } michael@0: michael@0: // Tests constructing a tuple from its fields. michael@0: TEST(TupleConstructorTest, ConstructsFromFields) { michael@0: int n = 1; michael@0: // Reference field. michael@0: tuple a(n); michael@0: EXPECT_EQ(&n, &(get<0>(a))); michael@0: michael@0: // Non-reference fields. michael@0: tuple b(5, 'a'); michael@0: EXPECT_EQ(5, get<0>(b)); michael@0: EXPECT_EQ('a', get<1>(b)); michael@0: michael@0: // Const reference field. michael@0: const int m = 2; michael@0: tuple c(true, m); michael@0: EXPECT_TRUE(get<0>(c)); michael@0: EXPECT_EQ(&m, &(get<1>(c))); michael@0: } michael@0: michael@0: // Tests tuple's copy constructor. michael@0: TEST(TupleConstructorTest, CopyConstructor) { michael@0: tuple a(0.0, true); michael@0: tuple b(a); michael@0: michael@0: EXPECT_DOUBLE_EQ(0.0, get<0>(b)); michael@0: EXPECT_TRUE(get<1>(b)); michael@0: } michael@0: michael@0: // Tests constructing a tuple from another tuple that has a compatible michael@0: // but different type. michael@0: TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) { michael@0: tuple a(0, 1, 'a'); michael@0: tuple b(a); michael@0: michael@0: EXPECT_DOUBLE_EQ(0.0, get<0>(b)); michael@0: EXPECT_EQ(1, get<1>(b)); michael@0: EXPECT_EQ('a', get<2>(b)); michael@0: } michael@0: michael@0: // Tests constructing a 2-tuple from an std::pair. michael@0: TEST(TupleConstructorTest, ConstructsFromPair) { michael@0: ::std::pair a(1, 'a'); michael@0: tuple b(a); michael@0: tuple c(a); michael@0: } michael@0: michael@0: // Tests assigning a tuple to another tuple with the same type. michael@0: TEST(TupleAssignmentTest, AssignsToSameTupleType) { michael@0: const tuple a(5, 7L); michael@0: tuple b; michael@0: b = a; michael@0: EXPECT_EQ(5, get<0>(b)); michael@0: EXPECT_EQ(7L, get<1>(b)); michael@0: } michael@0: michael@0: // Tests assigning a tuple to another tuple with a different but michael@0: // compatible type. michael@0: TEST(TupleAssignmentTest, AssignsToDifferentTupleType) { michael@0: const tuple a(1, 7L, true); michael@0: tuple b; michael@0: b = a; michael@0: EXPECT_EQ(1L, get<0>(b)); michael@0: EXPECT_EQ(7, get<1>(b)); michael@0: EXPECT_TRUE(get<2>(b)); michael@0: } michael@0: michael@0: // Tests assigning an std::pair to a 2-tuple. michael@0: TEST(TupleAssignmentTest, AssignsFromPair) { michael@0: const ::std::pair a(5, true); michael@0: tuple b; michael@0: b = a; michael@0: EXPECT_EQ(5, get<0>(b)); michael@0: EXPECT_TRUE(get<1>(b)); michael@0: michael@0: tuple c; michael@0: c = a; michael@0: EXPECT_EQ(5L, get<0>(c)); michael@0: EXPECT_TRUE(get<1>(c)); michael@0: } michael@0: michael@0: // A fixture for testing big tuples. michael@0: class BigTupleTest : public testing::Test { michael@0: protected: michael@0: typedef tuple BigTuple; michael@0: michael@0: BigTupleTest() : michael@0: a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2), michael@0: b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {} michael@0: michael@0: BigTuple a_, b_; michael@0: }; michael@0: michael@0: // Tests constructing big tuples. michael@0: TEST_F(BigTupleTest, Construction) { michael@0: BigTuple a; michael@0: BigTuple b(b_); michael@0: } michael@0: michael@0: // Tests that get(t) returns the N-th (0-based) field of tuple t. michael@0: TEST_F(BigTupleTest, get) { michael@0: EXPECT_EQ(1, get<0>(a_)); michael@0: EXPECT_EQ(2, get<9>(a_)); michael@0: michael@0: // Tests that get() works on a const tuple too. michael@0: const BigTuple a(a_); michael@0: EXPECT_EQ(1, get<0>(a)); michael@0: EXPECT_EQ(2, get<9>(a)); michael@0: } michael@0: michael@0: // Tests comparing big tuples. michael@0: TEST_F(BigTupleTest, Comparisons) { michael@0: EXPECT_TRUE(a_ == a_); michael@0: EXPECT_FALSE(a_ != a_); michael@0: michael@0: EXPECT_TRUE(a_ != b_); michael@0: EXPECT_FALSE(a_ == b_); michael@0: } michael@0: michael@0: TEST(MakeTupleTest, WorksForScalarTypes) { michael@0: tuple a; michael@0: a = make_tuple(true, 5); michael@0: EXPECT_TRUE(get<0>(a)); michael@0: EXPECT_EQ(5, get<1>(a)); michael@0: michael@0: tuple b; michael@0: b = make_tuple('a', 'b', 5); michael@0: EXPECT_EQ('a', get<0>(b)); michael@0: EXPECT_EQ('b', get<1>(b)); michael@0: EXPECT_EQ(5, get<2>(b)); michael@0: } michael@0: michael@0: TEST(MakeTupleTest, WorksForPointers) { michael@0: int a[] = { 1, 2, 3, 4 }; michael@0: const char* const str = "hi"; michael@0: int* const p = a; michael@0: michael@0: tuple t; michael@0: t = make_tuple(str, p); michael@0: EXPECT_EQ(str, get<0>(t)); michael@0: EXPECT_EQ(p, get<1>(t)); michael@0: } michael@0: michael@0: } // namespace