Hash :
d4083c79
        
        Author :
  
        
        Date :
2025-01-31T15:06:36
        
      
Metal: Make ObjCPtr available to all modules Move ObjCPtr implementation to src/common/ObjCPtr.h, angle::ObjCPtr so that it's available also outside libANGLE. Bug: angleproject:393263506 Change-Id: I8ecd5632c7ae33ef4b409fc820fad229e91bc0ab Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6219318 Auto-Submit: Kimmo Kinnunen <kkinnunen@apple.com> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Kimmo Kinnunen <kkinnunen@apple.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
//
// Copyright 2025 The ANGLE Project Authors. All rights reserved.
//   of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ObjCPtr_test.cpp:
//   Test for functionality in ObjCPtr.h
#import "common/apple/ObjCPtr.h"
#import <Metal/Metal.h>
#import "gtest/gtest.h"
namespace
{
using namespace angle;
// This explains why the implementation has ObjCPtr<U> &&other constructor/operator=
// as opposed to ObjCPtr &&other ones.
TEST(ObjCPtrTest, ImplementationDetailExplanation)
{
    // For Obj-C interfaces we would like the client to use ObjCPtr<T> form, similar
    // to any C++ smart pointer.
    MTLStencilDescriptor *rawDesc             = nil;
    ObjCPtr<MTLStencilDescriptor> stencilDesc = adoptObjCPtr(rawDesc);
    // For Obj-C protocols we would like the client to use ObjCPtr<id<P>> form,
    // which resembles the normal smart pointer form textually:
    id<MTLDevice> rawDevice       = nil;
    ObjCPtr<id<MTLDevice>> device = adoptObjCPtr(rawDevice);
    // adoptObjCPtr for Obj-C interface types works as expected:
    {
        auto result = adoptObjCPtr(rawDesc);
        static_assert(std::is_same_v<ObjCPtr<MTLStencilDescriptor>, decltype(result)>);
    }
    // adoptObjCPtr for protocols does not:
    {
        auto result = adoptObjCPtr(rawDevice);
        static_assert(!std::is_same_v<ObjCPtr<id<MTLDevice>>, decltype(result)>);
        static_assert(
            std::is_same_v<ObjCPtr<std::remove_pointer_t<id<MTLDevice>>>, decltype(result)>);
    }
}
TEST(ObjCPtrTest, Comparison)
{
    ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
    ObjCPtr<MTLStencilDescriptor> b;
    EXPECT_TRUE(a == a);
    EXPECT_TRUE(a != b);
    EXPECT_TRUE(a != nullptr);
    EXPECT_TRUE(b == nullptr);
    EXPECT_TRUE(nullptr != a);
    EXPECT_TRUE(nullptr == b);
    EXPECT_TRUE(a != nil);
    EXPECT_TRUE(b == nil);
    EXPECT_TRUE(nil != a);
    EXPECT_TRUE(nil == b);
    EXPECT_TRUE(!!a);
    EXPECT_TRUE(!b);
}
TEST(ObjCPtrTest, Copy)
{
    ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
    ObjCPtr<MTLStencilDescriptor> b = a;
    EXPECT_EQ(a, b);
    EXPECT_NE(a, nullptr);
    a = {};
    EXPECT_NE(a, b);
}
TEST(ObjCPtrTest, LeakObject)
{
    ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
    EXPECT_NE(a, nullptr);
    auto rawA = a.leakObject();
    EXPECT_EQ(a, nullptr);
    EXPECT_EQ(a.leakObject(), nullptr);
    a = adoptObjCPtr(rawA);
}
TEST(ObjCPtrTest, SelfAssignment)
{
    ObjCPtr a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
    auto rawA = a.get();
    auto &r   = a;
    a         = r;
    EXPECT_EQ(a, rawA);
    a = std::move(r);
    EXPECT_EQ(a, rawA);
}
}  // namespace