Skip to content

Commit

Permalink
Address compile-time issues for shared_ptr of array types (#4721)
Browse files Browse the repository at this point in the history
* Address compile-time issues for shared_ptr of array types
  • Loading branch information
mversche authored and GitHub Enterprise committed May 8, 2024
1 parent 3c8c901 commit b3355be
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 14 deletions.
13 changes: 7 additions & 6 deletions groups/bsl/bslstl/bslstl_sharedptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2673,7 +2673,7 @@ class shared_ptr {
// Further note that the behavior of this method is the same as
// 'reset(source, object)'.

pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *> release()
pair<element_type *, BloombergLP::bslma::SharedPtrRep *> release()
BSLS_KEYWORD_NOEXCEPT;
// Return the pair consisting of the addresses of the modifiable
// 'ELEMENT_TYPE' object referred to, and the representation shared by,
Expand Down Expand Up @@ -2934,7 +2934,7 @@ class shared_ptr {
// 'use_count', and the result may be unreliable in multi-threaded code
// for the same reasons.

ELEMENT_TYPE *ptr() const BSLS_KEYWORD_NOEXCEPT;
element_type *ptr() const BSLS_KEYWORD_NOEXCEPT;
// [!DEPRECATED!] Use 'get' instead.
//
// Return the address providing modifiable access to the object
Expand Down Expand Up @@ -5289,7 +5289,7 @@ void shared_ptr<ELEMENT_TYPE>::swap(shared_ptr& other) BSLS_KEYWORD_NOEXCEPT
// Also, as 'shared_ptr' is bitwise-moveable, we could simplify this to
// 'memcpy'-ing through an (aligned?) array of sufficient 'char'.

ELEMENT_TYPE *tempPtr_p = d_ptr_p;
element_type *tempPtr_p = d_ptr_p;
d_ptr_p = other.d_ptr_p;
other.d_ptr_p = tempPtr_p;

Expand Down Expand Up @@ -5344,10 +5344,10 @@ shared_ptr<ELEMENT_TYPE>::loadAlias(const shared_ptr<ANY_TYPE>& source,
}

template <class ELEMENT_TYPE>
pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *>
pair<typename shared_ptr<ELEMENT_TYPE>::element_type *, BloombergLP::bslma::SharedPtrRep *>
shared_ptr<ELEMENT_TYPE>::release() BSLS_KEYWORD_NOEXCEPT
{
pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *> ret(d_ptr_p,
pair<element_type *, BloombergLP::bslma::SharedPtrRep *> ret(d_ptr_p,
d_rep_p);
d_ptr_p = 0;
d_rep_p = 0;
Expand Down Expand Up @@ -5540,7 +5540,8 @@ int shared_ptr<ELEMENT_TYPE>::numReferences() const BSLS_KEYWORD_NOEXCEPT

template <class ELEMENT_TYPE>
inline
ELEMENT_TYPE *shared_ptr<ELEMENT_TYPE>::ptr() const BSLS_KEYWORD_NOEXCEPT
typename shared_ptr<ELEMENT_TYPE>::element_type *
shared_ptr<ELEMENT_TYPE>::ptr() const BSLS_KEYWORD_NOEXCEPT
{
return d_ptr_p;
}
Expand Down
196 changes: 195 additions & 1 deletion groups/bsl/bslstl/bslstl_sharedptr.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1735,6 +1735,28 @@ struct TypedDeleter{

} // close namespace support

// ======================
// class SimpleTestObject
// ======================

struct SimpleTestObject {
char d_text[10];
int d_count;

SimpleTestObject()
{
strcpy(d_text, "text");
d_count = 1;
}

~SimpleTestObject()
{
strcpy(d_text, "destroyed");
--d_count;
}
};


// *** 'NonPolymorphicTestBaseObject' CLASS HIERARCHY ***

// ==================================
Expand Down Expand Up @@ -5518,7 +5540,7 @@ void Harness::testCase32_DefaultAllocator()
testArg(B01, MOVE_01),
testArg(B02, MOVE_02),
testArg(B03, MOVE_03));
} break;
} break;
case 4: {
x = bsl::make_shared<const MyInplaceAllocatableObject>(
testArg(B01, MOVE_01),
Expand Down Expand Up @@ -18047,6 +18069,8 @@ int main(int argc, char *argv[])
//: the 'shared_ptr' held an custom (user-supplied) representation.
//: 8 Do the right thing for empty null pointers, which means tracking
//: our expected behavior for reference-counting deleters.
//: 9 That 'release' compiles and releases a 'shared_ptr' if the
//: 'ELEMENT_TYPE' is an array.
//
// Plan:
// Create shared pointers with various representations, release them
Expand Down Expand Up @@ -18137,6 +18161,61 @@ int main(int argc, char *argv[])
ASSERT(0 == ta.numBytesInUse());
}

if (verbose) printf("\nConcern: array types"
"\n====================\n");
{
#ifndef BSLS_PLATFORM_CMP_IBM
{
// XLC requires array extents to compile

const int numObjects = 5;

gNumConstructors = 0;
gNumDestructors = 0;

{
bsl::shared_ptr<CountConstructorsAndDestructors []> x =
bsl::make_shared<CountConstructorsAndDestructors[]>(numObjects);


ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == 0);

ASSERT(0 != x.get());
}

ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == numObjects);

}
#endif
{
// XLC requires array extents to compile

const int numObjects = 5;

gNumConstructors = 0;
gNumDestructors = 0;

{
bsl::shared_ptr<CountConstructorsAndDestructors[numObjects]> x =
bsl::make_shared<CountConstructorsAndDestructors[numObjects]>();


ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == 0);

ASSERT(0 != x.get());
}

ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == numObjects);

}

}


} break;
case 16: {
// --------------------------------------------------------------------
Expand Down Expand Up @@ -20921,6 +21000,85 @@ int main(int argc, char *argv[])
ASSERT(1 == numDeletes);
ASSERT(1 == numDeletes1);


if (verbose) printf("\tSwap of array types.\n");

{
#ifndef BSLS_PLATFORM_CMP_IBM
// XLC requires array extents to compile

{
bsl::shared_ptr<int[]> a;
bsl::shared_ptr<int[]> b;

a.swap(b);
ASSERT(!a);
ASSERT(!b);
}
{
// XLC requires array extents to compile

const int numObjects = 5;

gNumConstructors = 0;
gNumDestructors = 0;

{
bsl::shared_ptr<CountConstructorsAndDestructors []> a =
bsl::make_shared<CountConstructorsAndDestructors[]>(numObjects);
bsl::shared_ptr<CountConstructorsAndDestructors []> b;

a.swap(b);

ASSERT(!a);
ASSERT(b);

ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == 0);

}

ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == numObjects);

}
#endif
{
bsl::shared_ptr<int[5]> a;
bsl::shared_ptr<int[5]> b;

a.swap(b);
ASSERT(!a);
ASSERT(!b);
}
{
// XLC requires array extents to compile

const int numObjects = 5;

gNumConstructors = 0;
gNumDestructors = 0;

{
bsl::shared_ptr<CountConstructorsAndDestructors[5]> a =
bsl::make_shared<CountConstructorsAndDestructors[5]>();
bsl::shared_ptr<CountConstructorsAndDestructors [5]> b;

a.swap(b);

ASSERT(!a);
ASSERT(b);

ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == 0);

}

ASSERTV(gNumConstructors, gNumConstructors == numObjects);
ASSERTV(gNumDestructors, gNumDestructors == numObjects);
}
}

} break;
case 7: {
// --------------------------------------------------------------------
Expand Down Expand Up @@ -21691,6 +21849,42 @@ int main(int argc, char *argv[])
#endif // BDE_OMIT_INTERNAL_DEPRECATED
}


if (verbose) printf("\nTesting array type"
"\n-------------------\n");
{
const int numObjects = 5;

#ifndef BSLS_PLATFORM_CMP_IBM
// XLC requires array extents to compile
{

bsl::shared_ptr<SimpleTestObject[]> x(
new SimpleTestObject[numObjects]);

for (int i = 0; i < numObjects; ++i) {
ASSERT(0 == strcmp(x[i].d_text, "text"));
ASSERT(0 == strcmp(x.get()[i].d_text, "text"));
ASSERT(0 == strcmp(x.ptr()[i].d_text, "text"));
}
}
#endif
// XLC requires array extents to compile
{

bsl::shared_ptr<SimpleTestObject[numObjects]> x(
new SimpleTestObject[numObjects]);

for (int i = 0; i < numObjects; ++i) {
ASSERT(0 == strcmp(x[i].d_text, "text"));
ASSERT(0 == strcmp(x.get()[i].d_text, "text"));
ASSERT(0 == strcmp(x.ptr()[i].d_text, "text"));
}
}

}


ASSERT(1 == numDeletes);
ASSERT(numDeallocations == ta.numDeallocations());

Expand Down
15 changes: 8 additions & 7 deletions groups/bsl/bslstl/bslstl_sharedptr_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Tue Feb 27 11:06:10 2024
// Generated on Wed May 1 12:41:03 2024
// Command line: sim_cpp11_features.pl bslstl_sharedptr.h

#ifdef COMPILING_BSLSTL_SHAREDPTR_H
Expand Down Expand Up @@ -1459,7 +1459,7 @@ class shared_ptr {
// Further note that the behavior of this method is the same as
// 'reset(source, object)'.

pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *> release()
pair<element_type *, BloombergLP::bslma::SharedPtrRep *> release()
BSLS_KEYWORD_NOEXCEPT;
// Return the pair consisting of the addresses of the modifiable
// 'ELEMENT_TYPE' object referred to, and the representation shared by,
Expand Down Expand Up @@ -1720,7 +1720,7 @@ class shared_ptr {
// 'use_count', and the result may be unreliable in multi-threaded code
// for the same reasons.

ELEMENT_TYPE *ptr() const BSLS_KEYWORD_NOEXCEPT;
element_type *ptr() const BSLS_KEYWORD_NOEXCEPT;
// [!DEPRECATED!] Use 'get' instead.
//
// Return the address providing modifiable access to the object
Expand Down Expand Up @@ -4976,7 +4976,7 @@ void shared_ptr<ELEMENT_TYPE>::swap(shared_ptr& other) BSLS_KEYWORD_NOEXCEPT
// Also, as 'shared_ptr' is bitwise-moveable, we could simplify this to
// 'memcpy'-ing through an (aligned?) array of sufficient 'char'.

ELEMENT_TYPE *tempPtr_p = d_ptr_p;
element_type *tempPtr_p = d_ptr_p;
d_ptr_p = other.d_ptr_p;
other.d_ptr_p = tempPtr_p;

Expand Down Expand Up @@ -5568,10 +5568,10 @@ shared_ptr<ELEMENT_TYPE>::loadAlias(const shared_ptr<ANY_TYPE>& source,
}

template <class ELEMENT_TYPE>
pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *>
pair<typename shared_ptr<ELEMENT_TYPE>::element_type *, BloombergLP::bslma::SharedPtrRep *>
shared_ptr<ELEMENT_TYPE>::release() BSLS_KEYWORD_NOEXCEPT
{
pair<ELEMENT_TYPE *, BloombergLP::bslma::SharedPtrRep *> ret(d_ptr_p,
pair<element_type *, BloombergLP::bslma::SharedPtrRep *> ret(d_ptr_p,
d_rep_p);
d_ptr_p = 0;
d_rep_p = 0;
Expand Down Expand Up @@ -5764,7 +5764,8 @@ int shared_ptr<ELEMENT_TYPE>::numReferences() const BSLS_KEYWORD_NOEXCEPT

template <class ELEMENT_TYPE>
inline
ELEMENT_TYPE *shared_ptr<ELEMENT_TYPE>::ptr() const BSLS_KEYWORD_NOEXCEPT
typename shared_ptr<ELEMENT_TYPE>::element_type *
shared_ptr<ELEMENT_TYPE>::ptr() const BSLS_KEYWORD_NOEXCEPT
{
return d_ptr_p;
}
Expand Down

0 comments on commit b3355be

Please sign in to comment.