123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #import <Foundation/Foundation.h>
- #include <vector>
- #include "base/memory/ref_counted.h"
- #include "testing/platform_test.h"
- #if defined(__has_feature) && __has_feature(objc_arc)
- #error "This file must not be compiled with ARC."
- #endif
- // This test verifies assumptions about the murky world of interaction between
- // C++ objects and blocks. Just to make sure.
- namespace {
- using NoArcBlockTest = PlatformTest;
- class RefCountedObject : public base::RefCounted<RefCountedObject> {
- public:
- RefCountedObject() {}
- // Refcount is private in the superclass, fake it by counting how many times
- // release can be called until there is one count left, then retain the count
- // back.
- int refcount() {
- int count = 1;
- while (!HasOneRef()) {
- bool check = base::subtle::RefCountedBase::Release();
- EXPECT_FALSE(check);
- ++count;
- }
- for (int ii = 1; ii < count; ii++)
- base::subtle::RefCountedBase::AddRef();
- return count;
- }
- protected:
- friend base::RefCounted<RefCountedObject>;
- virtual ~RefCountedObject() {}
- };
- TEST_F(NoArcBlockTest, BlockAndCPlusPlus) {
- RefCountedObject* object = new RefCountedObject();
- object->AddRef();
- EXPECT_TRUE(object->HasOneRef());
- EXPECT_EQ(1, object->refcount());
- {
- scoped_refptr<RefCountedObject> object_test_ptr(object);
- EXPECT_EQ(2, object->refcount());
- }
- EXPECT_TRUE(object->HasOneRef());
- void (^heap_block)(int) = nil;
- {
- scoped_refptr<RefCountedObject> object_ptr(object);
- EXPECT_EQ(2, object->refcount());
- void* object_void_ptr = (void*)object;
- void (^stack_block)(int) = ^(int expected) {
- EXPECT_EQ(object_void_ptr, object_ptr.get());
- EXPECT_EQ(expected, object_ptr.get()->refcount());
- };
- stack_block(3);
- heap_block = [stack_block copy];
- stack_block(4);
- }
- heap_block(2);
- [heap_block release];
- EXPECT_TRUE(object->HasOneRef());
- {
- scoped_refptr<RefCountedObject> object_test2_ptr(object);
- EXPECT_EQ(2, object->refcount());
- }
- EXPECT_TRUE(object->HasOneRef());
- object->Release();
- }
- TEST_F(NoArcBlockTest, BlockAndVectors) {
- void (^heap_block)(void) = nil;
- {
- std::vector<int> vector;
- vector.push_back(0);
- vector.push_back(1);
- vector.push_back(2);
- void (^stack_block)(void) = ^{
- EXPECT_EQ(3ul, vector.size());
- EXPECT_EQ(2, vector[2]);
- };
- stack_block();
- vector[2] = 42;
- vector.push_back(22);
- stack_block();
- heap_block = [stack_block copy];
- stack_block();
- }
- heap_block();
- [heap_block release];
- }
- } // namespace
|