Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/third_party/libwebrtc/rtc_base/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 11 kB image not shown  

Quelle  strong_alias_unittest.cc   Sprache: C

 
/*
 *  Copyright 2019 The Chromium Authors. All rights reserved.
 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/strong_alias.h"

#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

#include "rtc_base/containers/flat_map.h"
#include "rtc_base/gunit.h"
#include "test/gmock.h"

// This is a copy of
// https://source.chromium.org/chromium/chromium/src/+/main:base/types/strong_alias_unittest.cc
// but adapted to use WebRTC's includes, remove unit tests that test the ostream
// operator (it's removed in this port) and other adaptations to pass lint.

namespace webrtc {
namespace {

// For test correctnenss, it's important that these getters return lexically
// incrementing values as `index` grows.
template <typename T>
T GetExampleValue(int index);

template <>
int GetExampleValue<int>(int index) {
  return 5 + index;
}
template <>
uint64_t GetExampleValue<uint64_t>(int index) {
  return 500U + index;
}

template <>
std::string GetExampleValue<std::string>(int index) {
  return std::string('a', index);
}

}  // namespace

template <typename T>
class StrongAliasTest : public ::testing::Test {};

using TestedTypes = ::testing::Types<int, uint64_t, std::string>;
TYPED_TEST_SUITE(StrongAliasTest, TestedTypes);

TYPED_TEST(StrongAliasTest, ValueAccessesUnderlyingValue) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;

  // Const value getter.
  const FooAlias const_alias(GetExampleValue<TypeParam>(1));
  EXPECT_EQ(GetExampleValue<TypeParam>(1), const_alias.value());
  static_assert(std::is_const<typename std::remove_reference<
                    decltype(const_alias.value())>::type>::value,
                "Reference returned by const value getter should be const.");
}

TYPED_TEST(StrongAliasTest, ExplicitConversionToUnderlyingValue) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;

  const FooAlias const_alias(GetExampleValue<TypeParam>(1));
  EXPECT_EQ(GetExampleValue<TypeParam>(1), static_cast<TypeParam>(const_alias));
}

TYPED_TEST(StrongAliasTest, CanBeCopyConstructed) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  FooAlias alias(GetExampleValue<TypeParam>(0));
  FooAlias copy_constructed = alias;
  EXPECT_EQ(copy_constructed, alias);

  FooAlias copy_assigned;
  copy_assigned = alias;
  EXPECT_EQ(copy_assigned, alias);
}

TYPED_TEST(StrongAliasTest, CanBeMoveConstructed) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  FooAlias alias(GetExampleValue<TypeParam>(0));
  FooAlias move_constructed = std::move(alias);
  EXPECT_EQ(move_constructed, FooAlias(GetExampleValue<TypeParam>(0)));

  FooAlias alias2(GetExampleValue<TypeParam>(2));
  FooAlias move_assigned;
  move_assigned = std::move(alias2);
  EXPECT_EQ(move_assigned, FooAlias(GetExampleValue<TypeParam>(2)));

  // Check that FooAlias is nothrow move constructible. This matters for
  // performance when used in std::vectors.
  static_assert(std::is_nothrow_move_constructible<FooAlias>::value,
                "Error: Alias is not nothow move constructible");
}

TYPED_TEST(StrongAliasTest, CanBeConstructedFromMoveOnlyType) {
  // Note, using a move-only unique_ptr to T:
  using FooAlias = StrongAlias<class FooTag, std::unique_ptr<TypeParam>>;

  FooAlias a(std::make_unique<TypeParam>(GetExampleValue<TypeParam>(0)));
  EXPECT_EQ(*a.value(), GetExampleValue<TypeParam>(0));

  auto bare_value = std::make_unique<TypeParam>(GetExampleValue<TypeParam>(1));
  FooAlias b(std::move(bare_value));
  EXPECT_EQ(*b.value(), GetExampleValue<TypeParam>(1));
}

TYPED_TEST(StrongAliasTest, MutableOperatorArrow) {
  // Note, using a move-only unique_ptr to T:
  using Ptr = std::unique_ptr<TypeParam>;
  using FooAlias = StrongAlias<class FooTag, Ptr>;

  FooAlias a(std::make_unique<TypeParam>());
  EXPECT_TRUE(a.value());

  // Check that `a` can be modified through the use of operator->.
  a->reset();

  EXPECT_FALSE(a.value());
}

TYPED_TEST(StrongAliasTest, MutableOperatorStar) {
  // Note, using a move-only unique_ptr to T:
  using Ptr = std::unique_ptr<TypeParam>;
  using FooAlias = StrongAlias<class FooTag, Ptr>;

  FooAlias a(std::make_unique<TypeParam>());
  FooAlias b(std::make_unique<TypeParam>());
  EXPECT_TRUE(*a);
  EXPECT_TRUE(*b);

  // Check that both the mutable l-value and r-value overloads work and we can
  // move out of the aliases.
  { Ptr ignore(*std::move(a)); }
  { Ptr ignore(std::move(*b)); }

  EXPECT_FALSE(a.value());
  EXPECT_FALSE(b.value());
}

TYPED_TEST(StrongAliasTest, MutableValue) {
  // Note, using a move-only unique_ptr to T:
  using Ptr = std::unique_ptr<TypeParam>;
  using FooAlias = StrongAlias<class FooTag, Ptr>;

  FooAlias a(std::make_unique<TypeParam>());
  FooAlias b(std::make_unique<TypeParam>());
  EXPECT_TRUE(a.value());
  EXPECT_TRUE(b.value());

  // Check that both the mutable l-value and r-value overloads work and we can
  // move out of the aliases.
  { Ptr ignore(std::move(a).value()); }
  { Ptr ignore(std::move(b.value())); }

  EXPECT_FALSE(a.value());
  EXPECT_FALSE(b.value());
}

TYPED_TEST(StrongAliasTest, SizeSameAsUnderlyingType) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  static_assert(sizeof(FooAlias) == sizeof(TypeParam),
                "StrongAlias should be as large as the underlying type.");
}

TYPED_TEST(StrongAliasTest, IsDefaultConstructible) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  static_assert(std::is_default_constructible<FooAlias>::value,
                "Should be possible to default-construct a StrongAlias.");
  static_assert(
      std::is_trivially_default_constructible<FooAlias>::value ==
          std::is_trivially_default_constructible<TypeParam>::value,
      "Should be possible to trivially default-construct a StrongAlias iff the "
      "underlying type is trivially default constructible.");
}

TEST(StrongAliasTest, TrivialTypeAliasIsStandardLayout) {
  using FooAlias = StrongAlias<class FooTag, int>;
  static_assert(std::is_standard_layout<FooAlias>::value,
                "int-based alias should have standard layout. ");
  static_assert(std::is_trivially_copyable<FooAlias>::value,
                "int-based alias should be trivially copyable. ");
}

TYPED_TEST(StrongAliasTest, CannotBeCreatedFromDifferentAlias) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  using BarAlias = StrongAlias<class BarTag, TypeParam>;
  static_assert(!std::is_constructible<FooAlias, BarAlias>::value,
                "Should be impossible to construct FooAlias from a BarAlias.");
  static_assert(!std::is_convertible<BarAlias, FooAlias>::value,
                "Should be impossible to convert a BarAlias into FooAlias.");
}

TYPED_TEST(StrongAliasTest, CannotBeImplicitlyConverterToUnderlyingValue) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  static_assert(!std::is_convertible<FooAlias, TypeParam>::value,
                "Should be impossible to implicitly convert a StrongAlias into "
                "an underlying type.");
}

TYPED_TEST(StrongAliasTest, ComparesEqualToSameValue) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  // Comparison to self:
  const FooAlias a = FooAlias(GetExampleValue<TypeParam>(0));
  EXPECT_EQ(a, a);
  EXPECT_FALSE(a != a);
  EXPECT_TRUE(a >= a);
  EXPECT_TRUE(a <= a);
  EXPECT_FALSE(a > a);
  EXPECT_FALSE(a < a);
  // Comparison to other equal object:
  const FooAlias b = FooAlias(GetExampleValue<TypeParam>(0));
  EXPECT_EQ(a, b);
  EXPECT_FALSE(a != b);
  EXPECT_TRUE(a >= b);
  EXPECT_TRUE(a <= b);
  EXPECT_FALSE(a > b);
  EXPECT_FALSE(a < b);
}

TYPED_TEST(StrongAliasTest, ComparesCorrectlyToDifferentValue) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  const FooAlias a = FooAlias(GetExampleValue<TypeParam>(0));
  const FooAlias b = FooAlias(GetExampleValue<TypeParam>(1));
  EXPECT_NE(a, b);
  EXPECT_FALSE(a == b);
  EXPECT_TRUE(b >= a);
  EXPECT_TRUE(a <= b);
  EXPECT_TRUE(b > a);
  EXPECT_TRUE(a < b);
}

TEST(StrongAliasTest, CanBeDerivedFrom) {
  // Aliases can be enriched by custom operations or validations if needed.
  // Ideally, one could go from a 'using' declaration to a derived class to add
  // those methods without the need to change any other code.
  class CountryCode : public StrongAlias<CountryCode, std::string> {
   public:
    explicit CountryCode(const std::string& value)
        : StrongAlias<CountryCode, std::string>::StrongAlias(value) {
      if (value_.length() != 2) {
        // Country code invalid!
        value_.clear();  // is_null() will return true.
      }
    }

    bool is_null() const { return value_.empty(); }
  };

  CountryCode valid("US");
  EXPECT_FALSE(valid.is_null());

  CountryCode invalid("United States");
  EXPECT_TRUE(invalid.is_null());
}

TEST(StrongAliasTest, CanWrapComplexStructures) {
  // A pair of strings implements odering and can, in principle, be used as
  // a base of StrongAlias.
  using PairOfStrings = std::pair<std::string, std::string>;
  using ComplexAlias = StrongAlias<class FooTag, PairOfStrings>;

  ComplexAlias a1{std::make_pair("aaa""bbb")};
  ComplexAlias a2{std::make_pair("ccc""ddd")};
  EXPECT_TRUE(a1 < a2);

  EXPECT_TRUE(a1.value() == PairOfStrings("aaa""bbb"));

  // Note a caveat, an std::pair doesn't have an overload of operator<<, and it
  // cannot be easily added since ADL rules would require it to be in the std
  // namespace. So we can't print ComplexAlias.
}

TYPED_TEST(StrongAliasTest, CanBeKeysInFlatMap) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  webrtc::flat_map<FooAlias, std::string> map;

  FooAlias k1(GetExampleValue<TypeParam>(0));
  FooAlias k2(GetExampleValue<TypeParam>(1));

  map[k1] = "value1";
  map[k2] = "value2";

  EXPECT_EQ(map[k1], "value1");
  EXPECT_EQ(map[k2], "value2");
}

TYPED_TEST(StrongAliasTest, CanBeKeysInStdMap) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  std::map<FooAlias, std::string> map;

  FooAlias k1(GetExampleValue<TypeParam>(0));
  FooAlias k2(GetExampleValue<TypeParam>(1));

  map[k1] = "value1";
  map[k2] = "value2";

  EXPECT_EQ(map[k1], "value1");
  EXPECT_EQ(map[k2], "value2");
}

TYPED_TEST(StrongAliasTest, CanDifferentiateOverloads) {
  using FooAlias = StrongAlias<class FooTag, TypeParam>;
  using BarAlias = StrongAlias<class BarTag, TypeParam>;
  class Scope {
   public:
    static std::string Overload(FooAlias) { return "FooAlias"; }
    static std::string Overload(BarAlias) { return "BarAlias"; }
  };
  EXPECT_EQ("FooAlias", Scope::Overload(FooAlias()));
  EXPECT_EQ("BarAlias", Scope::Overload(BarAlias()));
}

TEST(StrongAliasTest, EnsureConstexpr) {
  using FooAlias = StrongAlias<class FooTag, int>;

  // Check constructors.
  static constexpr FooAlias kZero{};
  static constexpr FooAlias kOne(1);

  // Check operator*.
  static_assert(*kZero == 0, "");
  static_assert(*kOne == 1, "");

  // Check value().
  static_assert(kZero.value() == 0, "");
  static_assert(kOne.value() == 1, "");

  // Check explicit conversions to underlying type.
  static_assert(static_cast<int>(kZero) == 0, "");
  static_assert(static_cast<int>(kOne) == 1, "");

  // Check comparison operations.
  static_assert(kZero == kZero, "");
  static_assert(kZero != kOne, "");
  static_assert(kZero < kOne, "");
  static_assert(kZero <= kOne, "");
  static_assert(kOne > kZero, "");
  static_assert(kOne >= kZero, "");
}

TEST(StrongAliasTest, BooleansAreEvaluatedAsBooleans) {
  using BoolAlias = StrongAlias<class BoolTag, bool>;

  BoolAlias happy(true);
  BoolAlias sad(false);

  EXPECT_TRUE(happy);
  EXPECT_FALSE(sad);
  EXPECT_TRUE(*happy);
  EXPECT_FALSE(*sad);
}
}  // namespace webrtc

Messung V0.5
C=90 H=100 G=95

¤ Dauer der Verarbeitung: 0.28 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.