Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/abseil-cpp/absl/cleanup/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  cleanup_test.cc   Sprache: C

 
// Copyright 2021 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
//
//      https://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/cleanup/cleanup.h"

#include <functional>
#include <type_traits>
#include <utility>

#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/utility/utility.h"

namespace {

using Tag = absl::cleanup_internal::Tag;

template <typename Type1, typename Type2>
constexpr bool IsSame() {
  return (std::is_same<Type1, Type2>::value);
}

struct IdentityFactory {
  template <typename Callback>
  static Callback AsCallback(Callback callback) {
    return Callback(std::move(callback));
  }
};

// `FunctorClass` is a type used for testing `absl::Cleanup`. It is intended to
// represent users that make their own move-only callback types outside of
// `std::function` and lambda literals.
class FunctorClass {
  using Callback = std::function<void()>;

 public:
  explicit FunctorClass(Callback callback) : callback_(std::move(callback)) {}

  FunctorClass(FunctorClass&& other)
      : callback_(std::exchange(other.callback_, Callback())) {}

  FunctorClass(const FunctorClass&) = delete;

  FunctorClass& operator=(const FunctorClass&) = delete;

  FunctorClass& operator=(FunctorClass&&) = delete;

  void operator()() const& = delete;

  void operator()() && {
    ASSERT_TRUE(callback_);
    callback_();
    callback_ = nullptr;
  }

 private:
  Callback callback_;
};

struct FunctorClassFactory {
  template <typename Callback>
  static FunctorClass AsCallback(Callback callback) {
    return FunctorClass(std::move(callback));
  }
};

struct StdFunctionFactory {
  template <typename Callback>
  static std::function<void()> AsCallback(Callback callback) {
    return std::function<void()>(std::move(callback));
  }
};

using CleanupTestParams =
    ::testing::Types<IdentityFactory, FunctorClassFactory, StdFunctionFactory>;
template <typename>
struct CleanupTest : public ::testing::Test {};
TYPED_TEST_SUITE(CleanupTest, CleanupTestParams);

bool fn_ptr_called = false;
void FnPtrFunction() { fn_ptr_called = true; }

TYPED_TEST(CleanupTest, FactoryProducesCorrectType) {
  {
    auto callback = TypeParam::AsCallback([] {});
    auto cleanup = absl::MakeCleanup(std::move(callback));

    static_assert(
        IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(),
        "");
  }

  {
    auto cleanup = absl::MakeCleanup(&FnPtrFunction);

    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
                  "");
  }

  {
    auto cleanup = absl::MakeCleanup(FnPtrFunction);

    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
                  "");
  }
}

#if defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION)
TYPED_TEST(CleanupTest, CTADProducesCorrectType) {
  {
    auto callback = TypeParam::AsCallback([] {});
    absl::Cleanup cleanup = std::move(callback);

    static_assert(
        IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(),
        "");
  }

  {
    absl::Cleanup cleanup = &FnPtrFunction;

    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
                  "");
  }

  {
    absl::Cleanup cleanup = FnPtrFunction;

    static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
                  "");
  }
}

TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) {
  {
    auto callback = IdentityFactory::AsCallback([] {});
    auto factory_cleanup = absl::MakeCleanup(callback);
    absl::Cleanup deduction_cleanup = callback;

    static_assert(
        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
  }

  {
    auto factory_cleanup =
        absl::MakeCleanup(FunctorClassFactory::AsCallback([] {}));
    absl::Cleanup deduction_cleanup = FunctorClassFactory::AsCallback([] {});

    static_assert(
        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
  }

  {
    auto factory_cleanup =
        absl::MakeCleanup(StdFunctionFactory::AsCallback([] {}));
    absl::Cleanup deduction_cleanup = StdFunctionFactory::AsCallback([] {});

    static_assert(
        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
  }

  {
    auto factory_cleanup = absl::MakeCleanup(&FnPtrFunction);
    absl::Cleanup deduction_cleanup = &FnPtrFunction;

    static_assert(
        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
  }

  {
    auto factory_cleanup = absl::MakeCleanup(FnPtrFunction);
    absl::Cleanup deduction_cleanup = FnPtrFunction;

    static_assert(
        IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
  }
}
#endif  // defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION)

TYPED_TEST(CleanupTest, BasicUsage) {
  bool called = false;

  {
    auto cleanup =
        absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; }));
    EXPECT_FALSE(called);  // Constructor shouldn't invoke the callback
  }

  EXPECT_TRUE(called);  // Destructor should invoke the callback
}

TYPED_TEST(CleanupTest, BasicUsageWithFunctionPointer) {
  fn_ptr_called = false;

  {
    auto cleanup = absl::MakeCleanup(TypeParam::AsCallback(&FnPtrFunction));
    EXPECT_FALSE(fn_ptr_called);  // Constructor shouldn't invoke the callback
  }

  EXPECT_TRUE(fn_ptr_called);  // Destructor should invoke the callback
}

TYPED_TEST(CleanupTest, Cancel) {
  bool called = false;

  {
    auto cleanup =
        absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; }));
    EXPECT_FALSE(called);  // Constructor shouldn't invoke the callback

    std::move(cleanup).Cancel();
    EXPECT_FALSE(called);  // Cancel shouldn't invoke the callback
  }

  EXPECT_FALSE(called);  // Destructor shouldn't invoke the callback
}

TYPED_TEST(CleanupTest, Invoke) {
  bool called = false;

  {
    auto cleanup =
        absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; }));
    EXPECT_FALSE(called);  // Constructor shouldn't invoke the callback

    std::move(cleanup).Invoke();
    EXPECT_TRUE(called);  // Invoke should invoke the callback

    called = false;  // Reset tracker before destructor runs
  }

  EXPECT_FALSE(called);  // Destructor shouldn't invoke the callback
}

TYPED_TEST(CleanupTest, Move) {
  bool called = false;

  {
    auto moved_from_cleanup =
        absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; }));
    EXPECT_FALSE(called);  // Constructor shouldn't invoke the callback

    {
      auto moved_to_cleanup = std::move(moved_from_cleanup);
      EXPECT_FALSE(called);  // Move shouldn't invoke the callback
    }

    EXPECT_TRUE(called);  // Destructor should invoke the callback

    called = false;  // Reset tracker before destructor runs
  }

  EXPECT_FALSE(called);  // Destructor shouldn't invoke the callback
}

int DestructionCount = 0;

struct DestructionCounter {
  void operator()() {}

  ~DestructionCounter() { ++DestructionCount; }
};

TYPED_TEST(CleanupTest, DestructorDestroys) {
  {
    auto cleanup =
        absl::MakeCleanup(TypeParam::AsCallback(DestructionCounter()));
    DestructionCount = 0;
  }

  EXPECT_EQ(DestructionCount, 1);  // Engaged cleanup destroys
}

TYPED_TEST(CleanupTest, CancelDestroys) {
  {
    auto cleanup =
        absl::MakeCleanup(TypeParam::AsCallback(DestructionCounter()));
    DestructionCount = 0;

    std::move(cleanup).Cancel();
    EXPECT_EQ(DestructionCount, 1);  // Cancel destroys
  }

  EXPECT_EQ(DestructionCount, 1);  // Canceled cleanup does not double destroy
}

TYPED_TEST(CleanupTest, InvokeDestroys) {
  {
    auto cleanup =
        absl::MakeCleanup(TypeParam::AsCallback(DestructionCounter()));
    DestructionCount = 0;

    std::move(cleanup).Invoke();
    EXPECT_EQ(DestructionCount, 1);  // Invoke destroys
  }

  EXPECT_EQ(DestructionCount, 1);  // Invoked cleanup does not double destroy
}

}  // namespace

Messung V0.5
C=89 H=100 G=94

¤ Dauer der Verarbeitung: 0.14 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.