Skip to content

Commit 088a010

Browse files
committed
DOC: Adapt enum section to strongly typed enums
Adapt section about enums to the adoption of strongly typed enums in ITK: InsightSoftwareConsortium/ITK@0dd31a6
1 parent ae7db1a commit 088a010

File tree

2 files changed

+135
-33
lines changed

2 files changed

+135
-33
lines changed

SoftwareGuide/Latex/Appendices/CodingStyleGuide.tex

Lines changed: 116 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -758,50 +758,112 @@ \subsection{Naming Class Data Members}
758758
lines for the sake of readability.
759759
760760
761-
\subsection{Naming Enums}
761+
\subsection{Naming Enumerations}
762762
\label{subsec:NamingEnums}
763763
764-
Enumeration list (\code{enum}) must declare its identifier before the
765-
enum-list is specified, it must start with capitals and be written with case
766-
change, it should generally add the \code{Type} appendix (e.g. \code{MyEnumType}),
767-
and the enum-list must be specified in capitals. The documentation or comments
768-
added for each enum-list entry, if necessary, need not to be aligned.
764+
ITK uses strongly-typed enumerations through the \code{enum class} keyword.
765+
Enumerations in ITK need to declared within a dedicated class and be declared
766+
as \code{public}. The class name must be appended with the \code{Enums} label
767+
(even when the class contains a single strongly-typed enumeration). Enumeration
768+
classes must declare their identifier before the enum-list is specified, it
769+
must start with capitals and be written with case change, and it shall not bear
770+
the \code{Type} appendix. The type of the enumeration must be defined
771+
explicitly. The streaming operator \code{<<} must be overloaded to define
772+
enumerations are printed. The enum-list must be specified in capitals. The
773+
documentation or comments added for each enum-list entry, if necessary, need
774+
not to be aligned.
775+
776+
For example,
777+
\small
778+
\begin{minted}[baselinestretch=1,fontsize=\footnotesize,linenos=false,bgcolor=ltgray]{cpp}
779+
/**
780+
* \class MathematicalMorphologyEnums
781+
* \brief Mathematical Morphology enum classes.
782+
* \ingroup ITKMathematicalMorphology
783+
*/
784+
785+
class MathematicalMorphologyEnums
786+
{
787+
public:
788+
/**\class Algorithm
789+
* \brief Algorithm or implementation used in the dilation/erosion operations.
790+
* \ingroup ITKMathematicalMorphology
791+
*/
792+
enum class Algorithm : uint8_t
793+
{
794+
BASIC = 0,
795+
HISTO = 1,
796+
ANCHOR = 2,
797+
VHGW = 3
798+
};
799+
};
800+
801+
/** Define how to print enumeration values. */
802+
extern ITKMathematicalMorphology_EXPORT std::ostream &
803+
operator<<(std::ostream & out, const MathematicalMorphologyEnums::Algorithm value);
804+
\end{minted}
805+
\normalsize
806+
807+
The enumeration streaming method needs to be defined the implementation file, e.g.:
769808
\small
770809
\begin{minted}[baselinestretch=1,fontsize=\footnotesize,linenos=false,bgcolor=ltgray]{cpp}
771-
/** Weight types. */
772-
enum WeightType {
773-
GOURAUD, // Uniform weights
774-
THURMER, // Angle on a triangle at the given vertex
775-
AREA // Doc alignment not needed
776-
};
810+
std::ostream &
811+
operator<<(std::ostream & out, const MathematicalMorphologyEnums::Algorithm value)
812+
{
813+
return out << [value] {
814+
switch (value)
815+
{
816+
case MathematicalMorphologyEnums::Algorithm::BASIC:
817+
return "itk::MathematicalMorphologyEnums::Algorithm::BASIC";
818+
case MathematicalMorphologyEnums::Algorithm::HISTO:
819+
return "itk::MathematicalMorphologyEnums::Algorithm::HISTO";
820+
case MathematicalMorphologyEnums::Algorithm::ANCHOR:
821+
return "itk::MathematicalMorphologyEnums::Algorithm::ANCHOR";
822+
case MathematicalMorphologyEnums::Algorithm::VHGW:
823+
return "itk::MathematicalMorphologyEnums::Algorithm::VHGW";
824+
default:
825+
return "INVALID VALUE FOR itk::MathematicalMorphologyEnums::Algorithm";
826+
}
827+
}();
828+
}
777829
\end{minted}
778830
\normalsize
779831
780-
No \code{typedef} keyword shall be added to an \code{enum}.
832+
Enumeration classes do not need to have their corresponding integral value
833+
specified, although it may be allowed (i.e. \code{BASIC = 0,}).
781834
782-
Enum-lists do not need to have their corresponding integral value specified
783-
(i.e. \code{GOURAUD = 0,}).
835+
For the sake of brevity aliases can be defined for an \code{enum class}. These
836+
shall be appended with the \code{Enum} label, e.g.
837+
\small
838+
\begin{minted}[baselinestretch=1,fontsize=\footnotesize,linenos=false,bgcolor=ltgray]{cpp}
839+
using AlgorithmEnum = MathematicalMorphologyEnums::Algorithm;
840+
\end{minted}
841+
\normalsize
784842
785-
When calling an enum-list entry from within a class, it should be called with
786-
the \code{Self::} class alias.
843+
When calling an \code{enum} class entry from within a class, it may not be called with
844+
the \code{Self::} class alias, e.g.
787845
\small
788846
\begin{minted}[baselinestretch=1,fontsize=\footnotesize,linenos=false,bgcolor=ltgray]{cpp}
789-
while( !m_OperationQ.empty() )
790-
{
791-
switch( m_OperationQ.front() )
792-
{
793-
case Self::SET_PRIORITY_LEVEL:
794-
m_PriorityLevel = m_LevelQ.front();
795-
m_LevelQ.pop();
796-
break;
797-
case Self::SET_LEVEL_FOR_FLUSHING:
798-
m_LevelForFlushing = m_LevelQ.front();
799-
m_LevelQ.pop();
800-
break;
801-
802-
...
803-
}
804-
}
847+
if (algo == AlgorithmEnum::BASIC)
848+
{
849+
m_BasicFilter->SetKernel(this->GetKernel());
850+
}
851+
else if (algo == AlgorithmEnum::HISTO)
852+
{
853+
m_HistogramFilter->SetKernel(this->GetKernel());
854+
}
855+
else if (flatKernel != nullptr && flatKernel->GetDecomposable() && algo == AlgorithmEnum::ANCHOR)
856+
{
857+
m_AnchorFilter->SetKernel(*flatKernel);
858+
}
859+
else if (flatKernel != nullptr && flatKernel->GetDecomposable() && algo == AlgorithmEnum::VHGW)
860+
{
861+
m_VHGWFilter->SetKernel(*flatKernel);
862+
}
863+
else
864+
{
865+
itkExceptionMacro(<< "Invalid algorithm");
866+
}
805867
\end{minted}
806868
\normalsize
807869
@@ -3735,6 +3797,27 @@ \subsection{Arguments in Tests}
37353797
\normalsize
37363798
37373799
3800+
\subsection{Testing Enumeration Streaming}
3801+
\label{subsec:TestEnumStreaming}
3802+
3803+
The enumeration class streaming operator overload needs to be tested, e.g.
3804+
\small
3805+
\begin{minted}[baselinestretch=1,fontsize=\footnotesize,linenos=false,bgcolor=ltgray]{cpp}
3806+
// Test streaming enumeration for MathematicalMorphologyEnums::Algorithm elements
3807+
const std::set<itk::MathematicalMorphologyEnums::Algorithm> allAlgorithm{
3808+
itk::MathematicalMorphologyEnums::Algorithm::BASIC,
3809+
itk::MathematicalMorphologyEnums::Algorithm::HISTO,
3810+
itk::MathematicalMorphologyEnums::Algorithm::ANCHOR,
3811+
itk::MathematicalMorphologyEnums::Algorithm::VHGW
3812+
};
3813+
for (const auto & ee : allAlgorithm)
3814+
{
3815+
std::cout << "STREAMED ENUM VALUE MathematicalMorphologyEnums::Algorithm: " << ee << std::endl;
3816+
}
3817+
\end{minted}
3818+
\normalsize
3819+
3820+
37383821
\subsection{Test Return Value}
37393822
\label{subsec:TestReturnValue}
37403823

SoftwareGuide/Latex/DevelopmentGuidelines/CreateAModule.tex

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,25 @@ \subsubsection{Wrapping Variables}
739739
740740
\normalsize
741741
742+
743+
\subsubsection{Wrapping Enumerations}
744+
745+
Enumeration classes need to be wrapped through the class they are declared in
746+
using the \code{itk\_wrap\_simple\_class}, e.g.:
747+
\small
748+
\begin{minted}[baselinestretch=1,fontsize=\footnotesize,linenos=false,bgcolor=ltgray]{cmake}
749+
itk_wrap_simple_class("itk::MathematicalMorphologyEnums")
750+
\end{minted}
751+
\normalsize
752+
753+
which results in access to the class in Python as
754+
\code{itk.MathematicalMorphologyEnum}, its \code{Algorithm} enumeration class
755+
being accesible as \code{itk.MathematicalMorphologyEnums.Algorithm}, and its
756+
enum-list being accessed as
757+
\code{itk.MathematicalMorphologyEnums.Algorithm\_BASIC},
758+
\code{itk.MathematicalMorphologyEnums.Algorithm\_HISTO}, etc.
759+
760+
742761
\subsubsection{Wrapping Macros}
743762
744763
There are a number of a wrapping macros called in the \code{wrapping/*.wrap}

0 commit comments

Comments
 (0)