@@ -311,3 +311,68 @@ TEST(SpTest, DoesNotCollapseOnTemplatedMove) {
311311
312312 EXPECT_FALSE (b->collapsed ) << " Constructor sp(U&&) was incorrectly used instead of templated move constructor" ;
313313}
314+
315+ TEST (SpTest, NumReferences) {
316+ sp<int > a;
317+ EXPECT_EQ (a.numReferences (), 0 );
318+
319+ sp<int > b (10 );
320+ EXPECT_EQ (b.numReferences (), 1 );
321+
322+ sp<int > c = b;
323+ EXPECT_EQ (b.numReferences (), 2 );
324+ EXPECT_EQ (c.numReferences (), 2 );
325+
326+ {
327+ sp<int > d = c;
328+ EXPECT_EQ (b.numReferences (), 3 );
329+ EXPECT_EQ (c.numReferences (), 3 );
330+ EXPECT_EQ (d.numReferences (), 3 );
331+ }
332+
333+ EXPECT_EQ (b.numReferences (), 2 );
334+ EXPECT_EQ (c.numReferences (), 2 );
335+
336+ b.reset ();
337+ EXPECT_EQ (b.numReferences (), 0 );
338+ EXPECT_EQ (c.numReferences (), 1 );
339+ }
340+
341+ TEST (SpTest, NumReferencesWithCOW) {
342+ sp<int > a (SpPointerType::UNIQUE, 5 );
343+ EXPECT_EQ (a.numReferences (), 1 );
344+
345+ sp<int > b = a;
346+ EXPECT_EQ (a.numReferences (), 2 );
347+ EXPECT_EQ (b.numReferences (), 2 );
348+
349+ b.mut () = 10 ; // Should detach
350+ EXPECT_EQ (a.numReferences (), 1 );
351+ EXPECT_EQ (b.numReferences (), 1 );
352+ }
353+
354+ TEST (SpTest, NumReferencesWithMove) {
355+ sp<int > a (5 );
356+ EXPECT_EQ (a.numReferences (), 1 );
357+
358+ sp<int > b (std::move (a));
359+ EXPECT_EQ (a.numReferences (), 0 );
360+ EXPECT_EQ (b.numReferences (), 1 );
361+ }
362+
363+ TEST (SpTest, NumReferencesWithTemplatedCopyMove) {
364+ struct Base { virtual ~Base () {} };
365+ struct Derived : Base {};
366+
367+ sp<Derived> d = sp<Derived>::create ();
368+ EXPECT_EQ (d.numReferences (), 1 );
369+
370+ sp<Base> b (d);
371+ EXPECT_EQ (d.numReferences (), 2 );
372+ EXPECT_EQ (b.numReferences (), 2 );
373+
374+ sp<Base> b2 (std::move (d));
375+ EXPECT_EQ (d.numReferences (), 0 );
376+ EXPECT_EQ (b.numReferences (), 2 );
377+ EXPECT_EQ (b2.numReferences (), 2 );
378+ }
0 commit comments