LCOV - code coverage report
Current view: top level - test/unittests/base - template-utils-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 32 32 100.0 %
Date: 2019-04-17 Functions: 14 19 73.7 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project 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 "src/base/template-utils.h"
       6             : 
       7             : #include "test/unittests/test-utils.h"
       8             : 
       9             : namespace v8 {
      10             : namespace base {
      11             : namespace template_utils_unittest {
      12             : 
      13             : ////////////////////////////
      14             : // Test make_array.
      15             : ////////////////////////////
      16             : 
      17             : namespace {
      18             : template <typename T, size_t Size>
      19           2 : void CheckArrayEquals(const std::array<T, Size>& arr1,
      20             :                       const std::array<T, Size>& arr2) {
      21          14 :   for (size_t i = 0; i < Size; ++i) {
      22           6 :     CHECK_EQ(arr1[i], arr2[i]);
      23             :   }
      24           2 : }
      25             : }  // namespace
      26             : 
      27       15443 : TEST(TemplateUtilsTest, MakeArraySimple) {
      28           1 :   auto computed_array = base::make_array<3>([](int i) { return 1 + (i * 3); });
      29           1 :   std::array<int, 3> expected{{1, 4, 7}};
      30           1 :   CheckArrayEquals(computed_array, expected);
      31           1 : }
      32             : 
      33             : namespace {
      34             : constexpr int doubleIntValue(int i) { return i * 2; }
      35             : }  // namespace
      36             : 
      37       15443 : TEST(TemplateUtilsTest, MakeArrayConstexpr) {
      38           1 :   constexpr auto computed_array = base::make_array<3>(doubleIntValue);
      39           1 :   constexpr std::array<int, 3> expected{{0, 2, 4}};
      40           1 :   CheckArrayEquals(computed_array, expected);
      41           1 : }
      42             : 
      43             : ////////////////////////////
      44             : // Test pass_value_or_ref.
      45             : ////////////////////////////
      46             : 
      47             : // Wrap into this helper struct, such that the type is printed on errors.
      48             : template <typename T1, typename T2>
      49             : struct CheckIsSame {
      50             :   static_assert(std::is_same<T1, T2>::value, "test failure");
      51             : };
      52             : 
      53             : #define TEST_PASS_VALUE_OR_REF0(remove_extend, expected, given)               \
      54             :   static_assert(                                                              \
      55             :       sizeof(CheckIsSame<expected,                                            \
      56             :                          pass_value_or_ref<given, remove_extend>::type>) > 0, \
      57             :       "check")
      58             : 
      59             : #define TEST_PASS_VALUE_OR_REF(expected, given)                          \
      60             :   static_assert(                                                         \
      61             :       sizeof(CheckIsSame<expected, pass_value_or_ref<given>::type>) > 0, \
      62             :       "check")
      63             : 
      64             : TEST_PASS_VALUE_OR_REF(int, int&);
      65             : TEST_PASS_VALUE_OR_REF(int, int&&);
      66             : TEST_PASS_VALUE_OR_REF(const char*, const char[14]);
      67             : TEST_PASS_VALUE_OR_REF(const char*, const char*&&);
      68             : TEST_PASS_VALUE_OR_REF(const char*, const char (&)[14]);
      69             : TEST_PASS_VALUE_OR_REF(const std::string&, std::string);
      70             : TEST_PASS_VALUE_OR_REF(const std::string&, std::string&);
      71             : TEST_PASS_VALUE_OR_REF(const std::string&, const std::string&);
      72             : TEST_PASS_VALUE_OR_REF(int, const int);
      73             : TEST_PASS_VALUE_OR_REF(int, const int&);
      74             : TEST_PASS_VALUE_OR_REF(const int*, const int*);
      75             : TEST_PASS_VALUE_OR_REF(const int*, const int* const);
      76             : TEST_PASS_VALUE_OR_REF0(false, const char[14], const char[14]);
      77             : TEST_PASS_VALUE_OR_REF0(false, const char[14], const char (&)[14]);
      78             : TEST_PASS_VALUE_OR_REF0(false, const std::string&, std::string);
      79             : TEST_PASS_VALUE_OR_REF0(false, const std::string&, std::string&);
      80             : TEST_PASS_VALUE_OR_REF0(false, const std::string&, const std::string&);
      81             : TEST_PASS_VALUE_OR_REF0(false, int, const int);
      82             : TEST_PASS_VALUE_OR_REF0(false, int, const int&);
      83             : 
      84             : //////////////////////////////
      85             : // Test has_output_operator.
      86             : //////////////////////////////
      87             : 
      88             : // Intrinsic types:
      89             : static_assert(has_output_operator<int>::value, "int can be output");
      90             : static_assert(has_output_operator<void*>::value, "void* can be output");
      91             : static_assert(has_output_operator<uint64_t>::value, "int can be output");
      92             : 
      93             : // Classes:
      94             : class TestClass1 {};
      95             : class TestClass2 {};
      96             : extern std::ostream& operator<<(std::ostream& str, const TestClass2&);
      97             : class TestClass3 {};
      98             : extern std::ostream& operator<<(std::ostream& str, TestClass3);
      99             : static_assert(!has_output_operator<TestClass1>::value,
     100             :               "TestClass1 can not be output");
     101             : static_assert(has_output_operator<TestClass2>::value,
     102             :               "non-const TestClass2 can be output");
     103             : static_assert(has_output_operator<const TestClass2>::value,
     104             :               "const TestClass2 can be output");
     105             : static_assert(has_output_operator<TestClass3>::value,
     106             :               "non-const TestClass3 can be output");
     107             : static_assert(has_output_operator<const TestClass3>::value,
     108             :               "const TestClass3 can be output");
     109             : 
     110             : //////////////////////////////
     111             : // Test fold.
     112             : //////////////////////////////
     113             : 
     114             : struct FoldAllSameType {
     115             :   constexpr uint32_t operator()(uint32_t a, uint32_t b) const { return a | b; }
     116             : };
     117             : static_assert(base::fold(FoldAllSameType{}, 3, 6) == 7, "check fold");
     118             : // Test that it works if implicit conversion is needed for one of the
     119             : // parameters.
     120             : static_assert(base::fold(FoldAllSameType{}, uint8_t{1}, 256) == 257,
     121             :               "check correct type inference");
     122             : // Test a single parameter.
     123             : static_assert(base::fold(FoldAllSameType{}, 25) == 25,
     124             :               "check folding a single argument");
     125             : 
     126       15443 : TEST(TemplateUtilsTest, FoldDifferentType) {
     127             :   auto fn = [](std::string str, char c) {
     128           3 :     str.push_back(c);
     129             :     return str;
     130             :   };
     131           3 :   CHECK_EQ(base::fold(fn, std::string("foo"), 'b', 'a', 'r'), "foobar");
     132           1 : }
     133             : 
     134       15443 : TEST(TemplateUtilsTest, FoldMoveOnlyType) {
     135             :   auto fn = [](std::unique_ptr<std::string> str, char c) {
     136           1 :     str->push_back(c);
     137             :     return str;
     138             :   };
     139             :   std::unique_ptr<std::string> str = base::make_unique<std::string>("foo");
     140             :   std::unique_ptr<std::string> folded =
     141           2 :       base::fold(fn, std::move(str), 'b', 'a', 'r');
     142           1 :   CHECK_NULL(str);
     143           1 :   CHECK_NOT_NULL(folded);
     144           1 :   CHECK_EQ(*folded, "foobar");
     145           1 : }
     146             : 
     147             : struct TemplatizedFoldFunctor {
     148             :   template <typename T, typename... Tup>
     149           1 :   std::tuple<Tup..., typename std::decay<T>::type> operator()(
     150             :       std::tuple<Tup...> tup, T&& val) {
     151             :     return std::tuple_cat(std::move(tup),
     152           1 :                           std::make_tuple(std::forward<T>(val)));
     153             :   }
     154             : };
     155       15443 : TEST(TemplateUtilsTest, FoldToTuple) {
     156             :   auto input = std::make_tuple(char{'x'}, int{4}, double{3.2},
     157           2 :                                std::unique_ptr<uint8_t>{}, std::string{"foo"});
     158             :   auto result =
     159             :       base::fold(TemplatizedFoldFunctor{}, std::make_tuple(),
     160             :                  std::get<0>(input), std::get<1>(input), std::get<2>(input),
     161           1 :                  std::unique_ptr<uint8_t>{}, std::get<4>(input));
     162             :   static_assert(std::is_same<decltype(result), decltype(input)>::value,
     163             :                 "the resulting tuple should have the same type as the input");
     164             :   DCHECK_EQ(input, result);
     165           1 : }
     166             : 
     167             : }  // namespace template_utils_unittest
     168             : }  // namespace base
     169        9264 : }  // namespace v8

Generated by: LCOV version 1.10