tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

overload_test.cc (6293B)


      1 // Copyright 2023 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "absl/functional/overload.h"
     16 
     17 #include <cstdint>
     18 #include <string>
     19 #include <type_traits>
     20 
     21 #include "gtest/gtest.h"
     22 #include "absl/base/config.h"
     23 #include "absl/strings/str_cat.h"
     24 #include "absl/strings/string_view.h"
     25 #include "absl/types/variant.h"
     26 
     27 namespace {
     28 
     29 TEST(OverloadTest, DispatchConsidersTypeWithAutoFallback) {
     30  auto overloaded = absl::Overload{
     31      [](int v) { return absl::StrCat("int ", v); },
     32      [](double v) { return absl::StrCat("double ", v); },
     33      [](const char* v) { return absl::StrCat("const char* ", v); },
     34      [](auto v) { return absl::StrCat("auto ", v); },
     35  };
     36 
     37  EXPECT_EQ("int 1", overloaded(1));
     38  EXPECT_EQ("double 2.5", overloaded(2.5));
     39  EXPECT_EQ("const char* hello", overloaded("hello"));
     40  EXPECT_EQ("auto 1.5", overloaded(1.5f));
     41 }
     42 
     43 TEST(OverloadTest, DispatchConsidersNumberOfArguments) {
     44  auto overloaded = absl::Overload{
     45      [](int a) { return a + 1; },
     46      [](int a, int b) { return a * b; },
     47      []() -> absl::string_view { return "none"; },
     48  };
     49 
     50  EXPECT_EQ(3, overloaded(2));
     51  EXPECT_EQ(21, overloaded(3, 7));
     52  EXPECT_EQ("none", overloaded());
     53 }
     54 
     55 TEST(OverloadTest, SupportsConstantEvaluation) {
     56  auto overloaded = absl::Overload{
     57      [](int a) { return a + 1; },
     58      [](int a, int b) { return a * b; },
     59      []() -> absl::string_view { return "none"; },
     60  };
     61 
     62  static_assert(overloaded() == "none");
     63  static_assert(overloaded(2) == 3);
     64  static_assert(overloaded(3, 7) == 21);
     65 }
     66 
     67 TEST(OverloadTest, PropogatesDefaults) {
     68  auto overloaded = absl::Overload{
     69      [](int a, int b = 5) { return a * b; },
     70      [](double c) { return c; },
     71  };
     72 
     73  EXPECT_EQ(21, overloaded(3, 7));
     74  EXPECT_EQ(35, overloaded(7));
     75  EXPECT_EQ(2.5, overloaded(2.5));
     76 }
     77 
     78 TEST(OverloadTest, AmbiguousWithDefaultsNotInvocable) {
     79  auto overloaded = absl::Overload{
     80      [](int a, int b = 5) { return a * b; },
     81      [](int c) { return c; },
     82  };
     83 
     84  static_assert(!std::is_invocable_v<decltype(overloaded), int>);
     85  static_assert(std::is_invocable_v<decltype(overloaded), int, int>);
     86 }
     87 
     88 TEST(OverloadTest, AmbiguousDuplicatesNotInvocable) {
     89  auto overloaded = absl::Overload{
     90      [](int a) { return a; },
     91      [](int c) { return c; },
     92  };
     93 
     94  static_assert(!std::is_invocable_v<decltype(overloaded), int>);
     95 }
     96 
     97 TEST(OverloadTest, AmbiguousConversionNotInvocable) {
     98  auto overloaded = absl::Overload{
     99      [](uint16_t a) { return a; },
    100      [](uint64_t c) { return c; },
    101  };
    102 
    103  static_assert(!std::is_invocable_v<decltype(overloaded), int>);
    104 }
    105 
    106 TEST(OverloadTest, AmbiguousConversionWithAutoNotInvocable) {
    107  auto overloaded = absl::Overload{
    108      [](auto a) { return a; },
    109      [](auto c) { return c; },
    110  };
    111 
    112  static_assert(!std::is_invocable_v<decltype(overloaded), int>);
    113 }
    114 
    115 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
    116 
    117 TEST(OverloadTest, AmbiguousConversionWithAutoAndTemplateNotInvocable) {
    118  auto overloaded = absl::Overload{
    119      [](auto a) { return a; },
    120      []<class T>(T c) { return c; },
    121  };
    122 
    123  static_assert(!std::is_invocable_v<decltype(overloaded), int>);
    124 }
    125 
    126 TEST(OverloadTest, DispatchConsidersTypeWithTemplateFallback) {
    127  auto overloaded = absl::Overload{
    128      [](int a) { return a; },
    129      []<class T>(T c) { return c * 2; },
    130  };
    131 
    132  EXPECT_EQ(7, overloaded(7));
    133  EXPECT_EQ(14.0, overloaded(7.0));
    134 }
    135 
    136 #endif  // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
    137 
    138 TEST(OverloadTest, DispatchConsidersSfinae) {
    139  auto overloaded = absl::Overload{
    140      [](auto a) -> decltype(a + 1) { return a + 1; },
    141  };
    142 
    143  static_assert(std::is_invocable_v<decltype(overloaded), int>);
    144  static_assert(!std::is_invocable_v<decltype(overloaded), std::string>);
    145 }
    146 
    147 TEST(OverloadTest, VariantVisitDispatchesCorrectly) {
    148  absl::variant<int, double, std::string> v(1);
    149  auto overloaded = absl::Overload{
    150      [](int) -> absl::string_view { return "int"; },
    151      [](double) -> absl::string_view { return "double"; },
    152      [](const std::string&) -> absl::string_view { return "string"; },
    153  };
    154 
    155  EXPECT_EQ("int", absl::visit(overloaded, v));
    156  v = 1.1;
    157  EXPECT_EQ("double", absl::visit(overloaded, v));
    158  v = "hello";
    159  EXPECT_EQ("string", absl::visit(overloaded, v));
    160 }
    161 
    162 TEST(OverloadTest, VariantVisitWithAutoFallbackDispatchesCorrectly) {
    163  absl::variant<std::string, int32_t, int64_t> v(int32_t{1});
    164  auto overloaded = absl::Overload{
    165      [](const std::string& s) { return s.size(); },
    166      [](const auto& s) { return sizeof(s); },
    167  };
    168 
    169  EXPECT_EQ(4, absl::visit(overloaded, v));
    170  v = int64_t{1};
    171  EXPECT_EQ(8, absl::visit(overloaded, v));
    172  v = std::string("hello");
    173  EXPECT_EQ(5, absl::visit(overloaded, v));
    174 }
    175 
    176 // This API used to be exported as a function, so it should also work fine to
    177 // use parantheses when initializing it.
    178 TEST(OverloadTest, UseWithParentheses) {
    179  const auto overloaded =
    180      absl::Overload([](const std::string& s) { return s.size(); },
    181                     [](const auto& s) { return sizeof(s); });
    182 
    183  absl::variant<std::string, int32_t, int64_t> v(int32_t{1});
    184  EXPECT_EQ(4, absl::visit(overloaded, v));
    185 
    186  v = int64_t{1};
    187  EXPECT_EQ(8, absl::visit(overloaded, v));
    188 
    189  v = std::string("hello");
    190  EXPECT_EQ(5, absl::visit(overloaded, v));
    191 }
    192 
    193 TEST(OverloadTest, HasConstexprConstructor) {
    194  constexpr auto overloaded = absl::Overload{
    195      [](int v) { return absl::StrCat("int ", v); },
    196      [](double v) { return absl::StrCat("double ", v); },
    197      [](const char* v) { return absl::StrCat("const char* ", v); },
    198      [](auto v) { return absl::StrCat("auto ", v); },
    199  };
    200 
    201  EXPECT_EQ("int 1", overloaded(1));
    202  EXPECT_EQ("double 2.5", overloaded(2.5));
    203  EXPECT_EQ("const char* hello", overloaded("hello"));
    204  EXPECT_EQ("auto 1.5", overloaded(1.5f));
    205 }
    206 
    207 }  // namespace