Skip to content

Commit 03ce742

Browse files
N-Dekkerdzenanz
authored andcommitted
STYLE: Allow conversion from nullptr to WeakPointer, not from zero
Small WeakPointer improvements: - Defaulted default-constructor (allowing the compiler to consider it "constexpr" and "noexcept") - Removed the other user-defined special functions (Rule Of Zero) - Removed redundant user-defined `operator=(ObjectType*)` - Added converting constructor, WeakPointer(std::nullptr_t). No longer allowed implicit conversion from the integer zero. Included GoogleTest unit tests.
1 parent 6af6956 commit 03ce742

File tree

3 files changed

+78
-27
lines changed

3 files changed

+78
-27
lines changed

Modules/Core/Common/include/itkWeakPointer.h

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,21 @@ class WeakPointer
4747
/** Extract information from template parameter. */
4848
using ObjectType = TObjectType;
4949

50-
/** Constructor. */
51-
WeakPointer() { m_Pointer = nullptr; }
50+
/** Explicitly-defaulted default-constructor.
51+
* \note The other five "special member functions" (copy-constructor,
52+
* copy-assignment operator, move-constructor, move-assignment operator,
53+
* and destructor) are defaulted implicitly, following the C++ "Rule of Zero".
54+
*/
55+
WeakPointer() = default;
5256

53-
/** Copy constructor. */
54-
WeakPointer(const WeakPointer<ObjectType> & p) = default;
55-
56-
/** Move constructor */
57-
WeakPointer(WeakPointer<ObjectType> && p) = default;
57+
/** Constructor, converting from `nullptr`. */
58+
WeakPointer(std::nullptr_t) {}
5859

5960
/** Constructor to pointer p. */
6061
WeakPointer(ObjectType * p)
6162
: m_Pointer(p)
6263
{}
6364

64-
/** Destructor. */
65-
~WeakPointer() = default;
66-
6765
/** Overload operator ->. */
6866
ObjectType * operator->() const { return m_Pointer; }
6967

@@ -134,22 +132,6 @@ class WeakPointer
134132
return (void *)m_Pointer >= (void *)r.m_Pointer;
135133
}
136134

137-
/** Overload operator assignment. */
138-
// cppcheck-suppress operatorEqVarError
139-
WeakPointer &
140-
operator=(const WeakPointer & r) = default;
141-
142-
WeakPointer &
143-
operator=(WeakPointer && r) = default;
144-
145-
/** Overload operator assignment. */
146-
WeakPointer &
147-
operator=(ObjectType * r)
148-
{
149-
m_Pointer = r;
150-
return *this;
151-
}
152-
153135
/** Function to print object pointed to. */
154136
ObjectType *
155137
Print(std::ostream & os) const
@@ -168,7 +150,7 @@ class WeakPointer
168150

169151
private:
170152
/** The pointer to the object referred to by this smart pointer. */
171-
ObjectType * m_Pointer;
153+
ObjectType * m_Pointer{ nullptr };
172154
};
173155

174156
template <typename T>

Modules/Core/Common/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ set(ITKCommonGTests
621621
itkSizeGTest.cxx
622622
itkSmartPointerGTest.cxx
623623
itkVectorContainerGTest.cxx
624+
itkWeakPointerGTest.cxx
624625
itkCommonTypeTraitsGTest.cxx
625626
itkMetaDataDictionaryGTest.cxx
626627
)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*=========================================================================
2+
*
3+
* Copyright NumFOCUS
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0.txt
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*=========================================================================*/
18+
19+
#include "itkGTest.h"
20+
21+
#include "itkWeakPointer.h"
22+
#include "itkLightObject.h"
23+
24+
#include <type_traits> // For is_default_constructible, is_copy_constructible, etc.
25+
26+
namespace
27+
{
28+
using WeakPointerType = itk::WeakPointer<itk::LightObject>;
29+
30+
template <typename T>
31+
constexpr bool
32+
AllSpecialMemberFunctionsNoThrow()
33+
{
34+
return std::is_nothrow_default_constructible<T>::value && std::is_nothrow_copy_constructible<T>::value &&
35+
std::is_nothrow_copy_assignable<T>::value && std::is_nothrow_move_constructible<T>::value &&
36+
std::is_nothrow_move_assignable<T>::value && std::is_nothrow_destructible<T>::value;
37+
}
38+
39+
} // namespace
40+
41+
static_assert(AllSpecialMemberFunctionsNoThrow<WeakPointerType>(),
42+
"All special member functions should be non-throwing.");
43+
44+
45+
TEST(WeakPointer, DefaultConstructedEqualsNullptr)
46+
{
47+
ASSERT_EQ(WeakPointerType{}, nullptr);
48+
ASSERT_TRUE(WeakPointerType{} == nullptr);
49+
ASSERT_TRUE(nullptr == WeakPointerType{});
50+
}
51+
52+
53+
TEST(WeakPointer, ConvertedFromNullptrEqualsNullptr)
54+
{
55+
ASSERT_EQ(WeakPointerType{ nullptr }, nullptr);
56+
ASSERT_TRUE(WeakPointerType{ nullptr } == nullptr);
57+
ASSERT_TRUE(nullptr == WeakPointerType{ nullptr });
58+
}
59+
60+
61+
TEST(WeakPointer, AssignedFromNullptrEqualsNullptr)
62+
{
63+
WeakPointerType ptr;
64+
ptr = nullptr;
65+
ASSERT_EQ(ptr, nullptr);
66+
ASSERT_TRUE(ptr == nullptr);
67+
ASSERT_TRUE(nullptr == ptr);
68+
}

0 commit comments

Comments
 (0)