Repository: InsightSoftwareConsortium/ITK (language: python)

Issue:
Add `ITK_DEFAULT_COPY_AND_MOVE` and replace "manually" defaulted copy and move member function declarations
Aims to address issue #4645 "Defaulting copy constructor, copy assignment, move constructor, and move
assignment functions", reported by Jon Haitz Legarreta Gorroño (@jhlegarreta).


Discussion / hints:
Let's rebase after https://github.com/InsightSoftwareConsortium/ITK/pull/4659 to get green CI.

Fix patch:
diff --git a/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.h b/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.h
index 19d265597a3..e10a7700549 100644
--- a/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.h
+++ b/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.h
@@ -38,6 +38,8 @@ template <unsigned int TPointDimension = 3>
 class ITK_TEMPLATE_EXPORT ContourSpatialObjectPoint : public SpatialObjectPoint<TPointDimension>
 {
 public:
+  ITK_DEFAULT_COPY_AND_MOVE(ContourSpatialObjectPoint);
+
   using Self = ContourSpatialObjectPoint;
   using Superclass = SpatialObjectPoint<TPointDimension>;
   using PointType = Point<double, TPointDimension>;
@@ -47,9 +49,6 @@ class ITK_TEMPLATE_EXPORT ContourSpatialObjectPoint : public SpatialObjectPoint<
    *  in the ContourSpatialObjectPoint */
   ContourSpatialObjectPoint();
 
-  /** Copy Constructor */
-  ContourSpatialObjectPoint(const ContourSpatialObjectPoint & other);
-
   /** Default destructor. */
   ~ContourSpatialObjectPoint() override = default;
 
@@ -69,10 +68,6 @@ class ITK_TEMPLATE_EXPORT ContourSpatialObjectPoint : public SpatialObjectPoint<
   void
   SetNormalInObjectSpace(const CovariantVectorType & normal);
 
-  /** Copy a surface point to another. */
-  Self &
-  operator=(const ContourSpatialObjectPoint & rhs);
-
 protected:
   void
   PrintSelf(std::ostream & os, Indent indent) const override;
diff --git a/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.hxx b/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.hxx
index c2282ab61af..a19f05df1bf 100644
--- a/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.hxx
+++ b/Modules/Core/SpatialObjects/include/itkContourSpatialObjectPoint.hxx
@@ -29,14 +29,6 @@ ContourSpatialObjectPoint<TPointDimension>::ContourSpatialObjectPoint()
   m_PickedPointInObjectSpace.Fill(0);
 }
 
-template <unsigned int TPointDimension>
-ContourSpatialObjectPoint<TPointDimension>::ContourSpatialObjectPoint(const ContourSpatialObjectPoint & other)
-  : Superclass(other)
-{
-  this->m_NormalInObjectSpace = other.GetNormalInObjectSpace();
-  this->m_PickedPointInObjectSpace = other.GetPickedPointInObjectSpace();
-}
-
 template <unsigned int TPointDimension>
 void
 ContourSpatialObjectPoint<TPointDimension>::SetPickedPointInObjectSpace(const PointType & point)
@@ -65,19 +57,6 @@ ContourSpatialObjectPoint<TPointDimension>::GetNormalInObjectSpace() const -> co
   return m_NormalInObjectSpace;
 }
 
-template <unsigned int TPointDimension>
-auto
-ContourSpatialObjectPoint<TPointDimension>::operator=(const ContourSpatialObjectPoint & rhs) -> Self &
-{
-  if (this != &rhs)
-  {
-    Superclass::operator=(rhs);
-    this->m_NormalInObjectSpace = rhs.GetNormalInObjectSpace();
-    this->m_PickedPointInObjectSpace = rhs.GetPickedPointInObjectSpace();
-  }
-  return *this;
-}
-
 template <unsigned int TPointDimension>
 void
 ContourSpatialObjectPoint<TPointDimension>::PrintSelf(std::ostream & os, Indent indent) const
diff --git a/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.h b/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.h
index a22a14e2bed..48817621459 100644
--- a/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.h
+++ b/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.h
@@ -60,6 +60,8 @@ template <unsigned int TPointDimension = 3>
 class ITK_TEMPLATE_EXPORT DTITubeSpatialObjectPoint : public TubeSpatialObjectPoint<TPointDimension>
 {
 public:
+  ITK_DEFAULT_COPY_AND_MOVE(DTITubeSpatialObjectPoint);
+
   using Self = DTITubeSpatialObjectPoint;
   using Superclass = TubeSpatialObjectPoint<TPointDimension>;
   using PointType = Point<double, TPointDimension>;
@@ -83,9 +85,6 @@ class ITK_TEMPLATE_EXPORT DTITubeSpatialObjectPoint : public TubeSpatialObjectPo
    * DTITubeSpatialObjectPoint */
   DTITubeSpatialObjectPoint();
 
-  /** Copy Constructor */
-  DTITubeSpatialObjectPoint(const DTITubeSpatialObjectPoint & other);
-
   /** Default destructor. */
   ~DTITubeSpatialObjectPoint() override = default;
 
@@ -117,10 +116,6 @@ class ITK_TEMPLATE_EXPORT DTITubeSpatialObjectPoint : public TubeSpatialObjectPo
     return m_TensorMatrix;
   }
 
-  /** Copy one DTITubeSpatialObjectPoint to another. */
-  Self &
-  operator=(const DTITubeSpatialObjectPoint & rhs);
-
   /** Add a field to the point list. */
   void
   AddField(const char * name, float value);
diff --git a/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.hxx b/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.hxx
index a2c621d33f5..bf42b9c8376 100644
--- a/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.hxx
+++ b/Modules/Core/SpatialObjects/include/itkDTITubeSpatialObjectPoint.hxx
@@ -36,24 +36,6 @@ DTITubeSpatialObjectPoint<TPointDimension>::DTITubeSpatialObjectPoint()
   m_TensorMatrix[5] = 1;
 }
 
-template <unsigned int TPointDimension>
-DTITubeSpatialObjectPoint<TPointDimension>::DTITubeSpatialObjectPoint(const DTITubeSpatialObjectPoint & other)
-  : Superclass(other)
-{
-  m_Fields.clear();
-  const FieldListType & fields = other.GetFields();
-  auto                  it = fields.begin();
-  while (it != fields.end())
-  {
-    this->AddField(it->first.c_str(), it->second);
-    ++it;
-  }
-  for (unsigned int i = 0; i < 6; ++i)
-  {
-    m_TensorMatrix[i] = other.m_TensorMatrix[i];
-  }
-}
-
 template <unsigned int TPointDimension>
 void
 DTITubeSpatialObjectPoint<TPointDimension>::PrintSelf(std::ostream & os, Indent indent) const
@@ -173,28 +155,6 @@ DTITubeSpatialObjectPoint<TPointDimension>::GetField(DTITubeSpatialObjectPointFi
   return -1;
 }
 
-template <unsigned int TPointDimension>
-auto
-DTITubeSpatialObjectPoint<TPointDimension>::operator=(const DTITubeSpatialObjectPoint & rhs) -> Self &
-{
-  if (this != &rhs)
-  {
-    Superclass::operator=(rhs);
-    m_Fields.clear();
-    const FieldListType & fields = rhs.GetFields();
-    auto                  it = fields.begin();
-    while (it != fields.end())
-    {
-      this->AddField(it->first.c_str(), it->second);
-      ++it;
-    }
-    for (unsigned int i = 0; i < 6; ++i)
-    {
-      m_TensorMatrix[i] = rhs.m_TensorMatrix[i];
-    }
-  }
-  return *this;
-}
 } // end namespace itk
 
 #endif
diff --git a/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.h b/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.h
index b1b425a67da..8235cb8f986 100644
--- a/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.h
+++ b/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.h
@@ -43,6 +43,8 @@ template <unsigned int TPointDimension = 3>
 class ITK_TEMPLATE_EXPORT LineSpatialObjectPoint : public SpatialObjectPoint<TPointDimension>
 {
 public:
+  ITK_DEFAULT_COPY_AND_MOVE(LineSpatialObjectPoint);
+
   using Self = LineSpatialObjectPoint;
   using Superclass = SpatialObjectPoint<TPointDimension>;
   using PointType = Point<double, TPointDimension>;
@@ -52,9 +54,6 @@ class ITK_TEMPLATE_EXPORT LineSpatialObjectPoint : public SpatialObjectPoint<TPo
   /** Constructor */
   LineSpatialObjectPoint();
 
-  /** Copy Constructor */
-  LineSpatialObjectPoint(const LineSpatialObjectPoint & other);
-
   /** Destructor */
   ~LineSpatialObjectPoint() override = default;
 
@@ -66,10 +65,6 @@ class ITK_TEMPLATE_EXPORT LineSpatialObjectPoint : public SpatialObjectPoint<TPo
   void
   SetNormalInObjectSpace(CovariantVectorType & normal, unsigned int index);
 
-  /** Copy one LineSpatialObjectPoint to another */
-  Self &
-  operator=(const LineSpatialObjectPoint & rhs);
-
 protected:
   NormalArrayType m_NormalArrayInObjectSpace{};
 
diff --git a/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.hxx b/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.hxx
index 8ca2e82ab2c..f54d80a0a60 100644
--- a/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.hxx
+++ b/Modules/Core/SpatialObjects/include/itkLineSpatialObjectPoint.hxx
@@ -35,13 +35,6 @@ LineSpatialObjectPoint<TPointDimension>::LineSpatialObjectPoint()
   }
 }
 
-template <unsigned int TPointDimension>
-LineSpatialObjectPoint<TPointDimension>::LineSpatialObjectPoint(const LineSpatialObjectPoint & other)
-  : Superclass(other)
-{
-  this->m_NormalArrayInObjectSpace = other.m_NormalArrayInObjectSpace;
-}
-
 template <unsigned int TPointDimension>
 auto
 LineSpatialObjectPoint<TPointDimension>::GetNormalInObjectSpace(unsigned int index) const -> const CovariantVectorType &
@@ -66,19 +59,6 @@ LineSpatialObjectPoint<TPointDimension>::SetNormalInObjectSpace(CovariantVectorT
   m_NormalArrayInObjectSpace[index] = normal;
 }
 
-/** Copy a point to another */
-template <unsigned int TPointDimension>
-auto
-LineSpatialObjectPoint<TPointDimension>::operator=(const LineSpatialObjectPoint & rhs) -> Self &
-{
-  if (this != &rhs)
-  {
-    Superclass::operator=(rhs);
-    this->m_NormalArrayInObjectSpace = rhs.m_NormalArrayInObjectSpace;
-  }
-  return *this;
-}
-
 } // end namespace itk
 
 #endif
diff --git a/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.h b/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.h
index eeef852a04d..1eda86e6ca6 100644
--- a/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.h
+++ b/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.h
@@ -44,6 +44,8 @@ template <unsigned int TPointDimension = 3>
 class ITK_TEMPLATE_EXPORT SpatialObjectPoint
 {
 public:
+  ITK_DEFAULT_COPY_AND_MOVE(SpatialObjectPoint);
+
   using PointDimensionType = unsigned int;
 
   static constexpr PointDimensionType PointDimension = TPointDimension;
@@ -51,9 +53,6 @@ class ITK_TEMPLATE_EXPORT SpatialObjectPoint
   /** Constructor. */
   SpatialObjectPoint();
 
-  /** Copy Constructor. */
-  SpatialObjectPoint(const SpatialObjectPoint & other);
-
   /** Default destructor. */
   virtual ~SpatialObjectPoint() = default;
 
@@ -128,10 +127,6 @@ class ITK_TEMPLATE_EXPORT SpatialObjectPoint
   PointType
   GetPositionInWorldSpace() const;
 
-  /** Copy one SpatialObjectPoint to another */
-  Self &
-  operator=(const SpatialObjectPoint & rhs);
-
   /** Set/Get color of the point */
   void
   SetColor(ColorType color)
diff --git a/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.hxx b/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.hxx
index 7114539a14d..0fa4abcac08 100644
--- a/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.hxx
+++ b/Modules/Core/SpatialObjects/include/itkSpatialObjectPoint.hxx
@@ -39,16 +39,6 @@ SpatialObjectPoint<TPointDimension>::SpatialObjectPoint()
   m_SpatialObject = nullptr;
 }
 
-template <unsigned int TPointDimension>
-SpatialObjectPoint<TPointDimension>::SpatialObjectPoint(const SpatialObjectPoint & other)
-{
-  this->SetId(other.GetId());
-  this->SetPositionInObjectSpace(other.GetPositionInObjectSpace());
-  this->SetColor(other.GetColor());
-  this->SetSpatialObject(other.GetSpatialObject());
-  this->SetTagScalarDictionary(other.GetTagScalarDictionary());
-}
-
 template <unsigned int TPointDimension>
 void
 SpatialObjectPoint<TPointDimension>::SetPositionInWorldSpace(const PointType & point)
@@ -83,21 +73,6 @@ SpatialObjectPoint<TPointDimension>::SetColor(double r, double g, double b, doub
   m_Color.SetAlpha(a);
 }
 
-template <unsigned int TPointDimension>
-auto
-SpatialObjectPoint<TPointDimension>::operator=(const SpatialObjectPoint & rhs) -> Self &
-{
-  if (this != &rhs)
-  {
-    this->SetId(rhs.GetId());
-    this->SetPositionInObjectSpace(rhs.GetPositionInObjectSpace());
-    this->SetColor(rhs.GetColor());
-    this->SetTagScalarDictionary(rhs.GetTagScalarDictionary());
-    this->SetSpatialObject(rhs.GetSpatialObject());
-  }
-  return *this;
-}
-
 template <unsigned int TPointDimension>
 void
 SpatialObjectPoint<TPointDimension>::SetTagScalarValue(const std::string & tag, double value)
diff --git a/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.h b/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.h
index 4f1b1de43fe..c41f76980b2 100644
--- a/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.h
+++ b/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.h
@@ -39,6 +39,8 @@ template <unsigned int TPointDimension = 3>
 class ITK_TEMPLATE_EXPORT SurfaceSpatialObjectPoint : public SpatialObjectPoint<TPointDimension>
 {
 public:
+  ITK_DEFAULT_COPY_AND_MOVE(SurfaceSpatialObjectPoint);
+
   using Self = SurfaceSpatialObjectPoint;
   using Superclass = SpatialObjectPoint<TPointDimension>;
   using PointType = Point<double, TPointDimension>;
@@ -48,9 +50,6 @@ class ITK_TEMPLATE_EXPORT SurfaceSpatialObjectPoint : public SpatialObjectPoint<
   /** Constructor */
   SurfaceSpatialObjectPoint();
 
-  /** Copy Constructor */
-  SurfaceSpatialObjectPoint(const SurfaceSpatialObjectPoint & other);
-
   /** Destructor */
   ~SurfaceSpatialObjectPoint() override = default;
 
@@ -70,10 +69,6 @@ class ITK_TEMPLATE_EXPORT SurfaceSpatialObjectPoint : public SpatialObjectPoint<
   void
   SetNormalInWorldSpace(const CovariantVectorType & normal);
 
-  /** Copy one SurfaceSpatialObjectPoint to another. */
-  Self &
-  operator=(const SurfaceSpatialObjectPoint & rhs);
-
 protected:
   CovariantVectorType m_NormalInObjectSpace{};
 
diff --git a/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.hxx b/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.hxx
index 222e0ca8f54..a7585b3c453 100644
--- a/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.hxx
+++ b/Modules/Core/SpatialObjects/include/itkSurfaceSpatialObjectPoint.hxx
@@ -28,13 +28,6 @@ SurfaceSpatialObjectPoint<TPointDimension>::SurfaceSpatialObjectPoint()
   m_NormalInObjectSpace.Fill(0);
 }
 
-template <unsigned int TPointDimension>
-SurfaceSpatialObjectPoint<TPointDimension>::SurfaceSpatialObjectPoint(const SurfaceSpatialObjectPoint & other)
-  : Superclass(other)
-{
-  this->m_NormalInObjectSpace = other.m_NormalInObjectSpace;
-}
-
 template <unsigned int TPointDimension>
 void
 SurfaceSpatialObjectPoint<TPointDimension>::SetNormalInObjectSpace(const CovariantVectorType & normal)
@@ -83,17 +76,6 @@ SurfaceSpatialObjectPoint<TPointDimension>::PrintSelf(std::ostream & os, Indent
   os << indent << "NormalInObjectSpace: " << m_NormalInObjectSpace << std::endl;
 }
 
-template <unsigned int TPointDimension>
-auto
-SurfaceSpatialObjectPoint<TPointDimension>::operator=(const SurfaceSpatialObjectPoint & rhs) -> Self &
-{
-  if (this != &rhs)
-  {
-    Superclass::operator=(rhs);
-    this->SetNormalInObjectSpace(rhs.GetNormalInObjectSpace());
-  }
-  return *this;
-}
 } // end namespace itk
 
 #endif
diff --git a/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.h b/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.h
index 9df62a294a8..2b01626dc44 100644
--- a/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.h
+++ b/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.h
@@ -39,6 +39,8 @@ template <unsigned int TPointDimension = 3>
 class ITK_TEMPLATE_EXPORT TubeSpatialObjectPoint : public SpatialObjectPoint<TPointDimension>
 {
 public:
+  ITK_DEFAULT_COPY_AND_MOVE(TubeSpatialObjectPoint);
+
   using Self = TubeSpatialObjectPoint;
   using Superclass = SpatialObjectPoint<TPointDimension>;
   using PointType = Point<double, TPointDimension>;
@@ -49,9 +51,6 @@ class ITK_TEMPLATE_EXPORT TubeSpatialObjectPoint : public SpatialObjectPoint<TPo
    * TubeSpatialObjectPoint */
   TubeSpatialObjectPoint();
 
-  /** Copy Constructor */
-  TubeSpatialObjectPoint(const TubeSpatialObjectPoint & other);
-
   /** Default destructor. */
   ~TubeSpatialObjectPoint() override = default;
 
@@ -263,10 +262,6 @@ class ITK_TEMPLATE_EXPORT TubeSpatialObjectPoint : public SpatialObjectPoint<TPo
     return m_Alpha3;
   }
 
-  /** Copy one TubeSpatialObjectPoint to another */
-  Self &
-  operator=(const TubeSpatialObjectPoint & rhs);
-
 protected:
   VectorType          m_TangentInObjectSpace{};
   CovariantVectorType m_Normal1InObjectSpace{};
diff --git a/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.hxx b/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.hxx
index cf75d3c34ee..e9e535bcc2d 100644
--- a/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.hxx
+++ b/Modules/Core/SpatialObjects/include/itkTubeSpatialObjectPoint.hxx
@@ -42,27 +42,6 @@ TubeSpatialObjectPoint<TPointDimension>::TubeSpatialObjectPoint()
   m_Alpha3 = 0;
 }
 
-template <unsigned int TPointDimension>
-TubeSpatialObjectPoint<TPointDimension>::TubeSpatialObjectPoint(const TubeSpatialObjectPoint & other)
-  : Superclass(other)
-{
-  this->SetRadiusInObjectSpace(other.GetRadiusInObjectSpace());
-  this->SetTangentInObjectSpace(other.GetTangentInObjectSpace());
-  this->SetNormal1InObjectSpace(other.GetNormal1InObjectSpace());
-  this->SetNormal2InObjectSpace(other.GetNormal2InObjectSpace());
-
-  this->SetRidgeness(other.GetRidgeness());
-  this->SetMedialness(other.GetMedialness());
-  this->SetBranchness(other.GetBranchness());
-  this->SetCurvature(other.GetCurvature());
-  this->SetLevelness(other.GetLevelness());
-  this->SetRoundness(other.GetRoundness());
-  this->SetIntensity(other.GetIntensity());
-  this->SetAlpha1(other.GetAlpha1());
-  this->SetAlpha2(other.GetAlpha2());
-  this->SetAlpha3(other.GetAlpha3());
-}
-
 template <unsigned int TPointDimension>
 double
 TubeSpatialObjectPoint<TPointDimension>::GetRadiusInWorldSpace() const
@@ -203,32 +182,6 @@ TubeSpatialObjectPoint<TPointDimension>::PrintSelf(std::ostream & os, Indent ind
   os << indent << "RadiusInObjectSpace: " << m_RadiusInObjectSpace << std::endl;
 }
 
-template <unsigned int TPointDimension>
-auto
-TubeSpatialObjectPoint<TPointDimension>::operator=(const TubeSpatialObjectPoint & rhs) -> Self &
-{
-  if (this != &rhs)
-  {
-    Superclass::operator=(rhs);
-
-    this->SetRadiusInObjectSpace(rhs.GetRadiusInObjectSpace());
-    this->SetTangentInObjectSpace(rhs.GetTangentInObjectSpace());
-    this->SetNormal1InObjectSpace(rhs.GetNormal1InObjectSpace());
-    this->SetNormal2InObjectSpace(rhs.GetNormal2InObjectSpace());
-
-    this->SetRidgeness(rhs.GetRidgeness());
-    this->SetMedialness(rhs.GetMedialness());
-    this->SetBranchness(rhs.GetBranchness());
-    this->SetCurvature(rhs.GetCurvature());
-    this->SetLevelness(rhs.GetLevelness());
-    this->SetRoundness(rhs.GetRoundness());
-    this->SetIntensity(rhs.GetIntensity());
-    this->SetAlpha1(rhs.GetAlpha1());
-    this->SetAlpha2(rhs.GetAlpha2());
-    this->SetAlpha3(rhs.GetAlpha3());
-  }
-  return *this;
-}
 } // end namespace itk
 
 #endif


Test patch:
diff --git a/Modules/Core/SpatialObjects/test/CMakeLists.txt b/Modules/Core/SpatialObjects/test/CMakeLists.txt
index 3b8dccc50d7..7118810b2f4 100644
--- a/Modules/Core/SpatialObjects/test/CMakeLists.txt
+++ b/Modules/Core/SpatialObjects/test/CMakeLists.txt
@@ -222,5 +222,8 @@ itk_add_test(
   itkNewMetaObjectTypeTest
   ${ITK_TEST_OUTPUT_DIR}/NewMetaObjectType.meta)
 
-set(ITKSpatialObjectsGTests itkImageMaskSpatialObjectGTest.cxx)
+set(ITKSpatialObjectsGTests
+  itkImageMaskSpatialObjectGTest.cxx
+  itkSpatialObjectPointGTest.cxx
+)
 creategoogletestdriver(ITKSpatialObjects "${ITKSpatialObjects-Test_LIBRARIES}" "${ITKSpatialObjectsGTests}")
diff --git a/Modules/Core/SpatialObjects/test/itkSpatialObjectPointGTest.cxx b/Modules/Core/SpatialObjects/test/itkSpatialObjectPointGTest.cxx
new file mode 100644
index 00000000000..92b80d29fab
--- /dev/null
+++ b/Modules/Core/SpatialObjects/test/itkSpatialObjectPointGTest.cxx
@@ -0,0 +1,44 @@
+/*=========================================================================
+ *
+ *  Copyright NumFOCUS
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *         https://www.apache.org/licenses/LICENSE-2.0.txt
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *=========================================================================*/
+
+// First include the header files to be tested:
+#include "itkContourSpatialObjectPoint.h"
+#include "itkDTITubeSpatialObjectPoint.h"
+#include "itkLineSpatialObjectPoint.h"
+#include "itkSpatialObjectPoint.h"
+#include "itkSurfaceSpatialObjectPoint.h"
+#include "itkTubeSpatialObjectPoint.h"
+
+#include <type_traits> // For is_nothrow_move_constructible_v and is_nothrow_move_assignable_v.
+
+
+// Note: we cannot assert nothrow_move_constructible, because SpatialObjectPoint internally has an `std::map`, which may
+// not be nothrow_move_constructible, at least in C++17.
+static_assert(std::is_move_constructible_v<itk::ContourSpatialObjectPoint<>>);
+static_assert(std::is_move_constructible_v<itk::DTITubeSpatialObjectPoint<>>);
+static_assert(std::is_move_constructible_v<itk::LineSpatialObjectPoint<>>);
+static_assert(std::is_move_constructible_v<itk::SpatialObjectPoint<>>);
+static_assert(std::is_move_constructible_v<itk::SurfaceSpatialObjectPoint<>>);
+static_assert(std::is_move_constructible_v<itk::TubeSpatialObjectPoint<>>);
+
+static_assert(std::is_nothrow_move_assignable_v<itk::ContourSpatialObjectPoint<>>);
+static_assert(std::is_nothrow_move_assignable_v<itk::DTITubeSpatialObjectPoint<>>);
+static_assert(std::is_nothrow_move_assignable_v<itk::LineSpatialObjectPoint<>>);
+static_assert(std::is_nothrow_move_assignable_v<itk::SpatialObjectPoint<>>);
+static_assert(std::is_nothrow_move_assignable_v<itk::SurfaceSpatialObjectPoint<>>);
+static_assert(std::is_nothrow_move_assignable_v<itk::TubeSpatialObjectPoint<>>);