From c2e754829628d1e9b7a16b3389cfdace76950fdf Mon Sep 17 00:00:00 2001 From: misterg Date: Tue, 19 Sep 2017 16:54:40 -0400 Subject: Initial Commit --- absl/utility/utility_test.cc | 163 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 absl/utility/utility_test.cc (limited to 'absl/utility/utility_test.cc') diff --git a/absl/utility/utility_test.cc b/absl/utility/utility_test.cc new file mode 100644 index 00000000..62cb46f4 --- /dev/null +++ b/absl/utility/utility_test.cc @@ -0,0 +1,163 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/utility/utility.h" + +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/attributes.h" + +namespace { + +#ifdef _MSC_VER +// Warnings for unused variables in this test are false positives. On other +// platforms, they are suppressed by ABSL_ATTRIBUTE_UNUSED, but that doesn't +// work on MSVC. +// Both the unused variables and the name length warnings are due to calls +// to absl::make_index_sequence with very large values, creating very long type +// names. The resulting warnings are so long they make build output unreadable. +#pragma warning( push ) +#pragma warning( disable : 4503 ) // decorated name length exceeded +#pragma warning( disable : 4101 ) // unreferenced local variable +#endif // _MSC_VER + +using testing::StaticAssertTypeEq; +using testing::ElementsAre; + +TEST(IntegerSequenceTest, ValueType) { + StaticAssertTypeEq::value_type>(); + StaticAssertTypeEq::value_type>(); +} + +TEST(IntegerSequenceTest, Size) { + EXPECT_EQ(0, (absl::integer_sequence::size())); + EXPECT_EQ(1, (absl::integer_sequence::size())); + EXPECT_EQ(1, (absl::integer_sequence::size())); + EXPECT_EQ(2, (absl::integer_sequence::size())); + EXPECT_EQ(3, (absl::integer_sequence::size())); + EXPECT_EQ(3, (absl::integer_sequence::size())); + constexpr size_t sz = absl::integer_sequence::size(); + EXPECT_EQ(2, sz); +} + +TEST(IntegerSequenceTest, MakeIndexSequence) { + StaticAssertTypeEq, absl::make_index_sequence<0>>(); + StaticAssertTypeEq, absl::make_index_sequence<1>>(); + StaticAssertTypeEq, + absl::make_index_sequence<2>>(); + StaticAssertTypeEq, + absl::make_index_sequence<3>>(); +} + +TEST(IntegerSequenceTest, MakeIntegerSequence) { + StaticAssertTypeEq, + absl::make_integer_sequence>(); + StaticAssertTypeEq, + absl::make_integer_sequence>(); + StaticAssertTypeEq, + absl::make_integer_sequence>(); + StaticAssertTypeEq, + absl::make_integer_sequence>(); +} + +template +class Counter {}; + +template +void CountAll(absl::index_sequence) { + // We only need an alias here, but instantiate a variable to silence warnings + // for unused typedefs in some compilers. + ABSL_ATTRIBUTE_UNUSED Counter...> seq; +} + +// This test verifies that absl::make_index_sequence can handle large arguments +// without blowing up template instantiation stack, going OOM or taking forever +// to compile (there is hard 15 minutes limit imposed by forge). +TEST(IntegerSequenceTest, MakeIndexSequencePerformance) { + // O(log N) template instantiations. + // We only need an alias here, but instantiate a variable to silence warnings + // for unused typedefs in some compilers. + ABSL_ATTRIBUTE_UNUSED absl::make_index_sequence<(1 << 16) - 1> seq; + // O(N) template instantiations. + CountAll(absl::make_index_sequence<(1 << 8) - 1>()); +} + +template +auto ApplyFromTupleImpl(F f, const Tup& tup, absl::index_sequence) + -> decltype(f(std::get(tup)...)) { + return f(std::get(tup)...); +} + +template +using TupIdxSeq = absl::make_index_sequence::value>; + +template +auto ApplyFromTuple(F f, const Tup& tup) + -> decltype(ApplyFromTupleImpl(f, tup, TupIdxSeq{})) { + return ApplyFromTupleImpl(f, tup, TupIdxSeq{}); +} + +template +std::string Fmt(const T& x) { + std::ostringstream os; + os << x; + return os.str(); +} + +struct PoorStrCat { + template + std::string operator()(const Args&... args) const { + std::string r; + for (const auto& e : {Fmt(args)...}) r += e; + return r; + } +}; + +template +std::vector TupStringVecImpl(const Tup& tup, + absl::index_sequence) { + return {Fmt(std::get(tup))...}; +} + +template +std::vector TupStringVec(const std::tuple& tup) { + return TupStringVecImpl(tup, absl::index_sequence_for()); +} + +TEST(MakeIndexSequenceTest, ApplyFromTupleExample) { + PoorStrCat f{}; + EXPECT_EQ("12abc3.14", f(12, "abc", 3.14)); + EXPECT_EQ("12abc3.14", ApplyFromTuple(f, std::make_tuple(12, "abc", 3.14))); +} + +TEST(IndexSequenceForTest, Basic) { + StaticAssertTypeEq, absl::index_sequence_for<>>(); + StaticAssertTypeEq, absl::index_sequence_for>(); + StaticAssertTypeEq, + absl::index_sequence_for>(); +} + +TEST(IndexSequenceForTest, Example) { + EXPECT_THAT(TupStringVec(std::make_tuple(12, "abc", 3.14)), + ElementsAre("12", "abc", "3.14")); +} + +} // namespace + -- cgit v1.2.3