Skip to content

Commit

Permalink
ENH: Remove ITK implementation of standard C++11 features.
Browse files Browse the repository at this point in the history
  • Loading branch information
hjmjohnson committed Jun 6, 2024
1 parent 38382b6 commit e148489
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 305 deletions.
151 changes: 2 additions & 149 deletions Modules/Core/Common/include/itkEnableIf.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,154 +17,7 @@
*=========================================================================*/
#ifndef itkEnableIf_h
#define itkEnableIf_h

#include "itkMacro.h"

#if !defined(ITK_LEGACY_REMOVE)

namespace itk
{
/// \cond HIDE_META_PROGRAMMING
namespace mpl
{

/** \brief This is an implementation of the enable if idiom.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*
* Enable if is a common C++ meta-programming technique for example
* there is a boost implementation, for more information on its usage
* please see:
* https://www.boost.org/doc/libs/1_49_0/libs/utility/enable_if.html
*
* This template enables specialization of a templated function based
* on some traits or concepts. It is implemented with SFINAE.
*
* If the parameter V is true then the Type trait is the second
* template parameter, otherwise an implementation does not exist and
* with SFINAE another implementation may be chosen.
*
* Example:
\code
template< typename TType>
typename EnableIfC<
IsSame<TType, typename NumericTraits<TType>::ValueType>::Value,
TType >::Type
GetComponent(const TType pix,
unsigned int itkNotUsed( idx ) ) const
{
return pix;
}
\endcode
*
* \sa \c EnableIf
*/
template <bool V, typename TType = void>
struct EnableIfC
{};
/// \cond SPECIALIZATION_IMPLEMENTATION
template <typename TType>
struct EnableIfC<true, TType>
{
using Type = TType;
};
/// \endcond


/** \brief An implementation of the negation of the enable if idiom.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*
* \sa \c EnableIfC
* \sa \c DisableIf
*/
template <bool V, typename TType = void>
struct DisableIfC
{};
/// \cond SPECIALIZATION_IMPLEMENTATION
template <typename TType>
struct DisableIfC<false, TType>
{
using Type = TType;
};
/// \endcond

/** \brief simplified way to dispose of \c enable_if.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
* \tparam TCondition Condition type. It's expected to provide a boolean value
* through its \c Value member.
* \tparam TType Type to \em return when the \c TCondition is (a) true (type).
*
* This \em overload automatically fetches \c TCondition value. However, beware, it
* won't work with standard C++ traits or boost traits. Indeed, this \c
* enable_if overload expects the \em value to follow UpperCamelCase ITK naming
* policy instead of the standard snake_case policy.
*
* Example:
\code
template< typename TType>
typename EnableIf<
IsSame<TType, typename NumericTraits<TType>::ValueType>,
TType >::Type
GetComponent(const TType pix,
unsigned int itkNotUsed( idx ) ) const
{
return pix;
}
\endcode
* \sa \c EnableIfC
* \sa \c DisableIf
*/
template <class TCondition, class TType = void>
struct EnableIf : public EnableIfC<TCondition::Value, TType>
{};

/** \brief simplified way to dispose of \c disable_if.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
* \tparam TCondition Condition type. It's expected to provide a boolean value
* through its \c Value member.
* \tparam TType Type to \em return when the \c TCondition is (a) false (type).
*
* This \em overload automatically fetches \c TCondition value. However, beware, it
* won't work with standard C++ traits or boost traits. Indeed, this \c
* enable_if overload expects the \em value to follow UpperCamelCase ITK naming
* policy instead of the standard snake_case policy.
*
* Example:
\code
template< typename TType>
typename DisableIf<
mpl::Not_<IsSame<TType, typename NumericTraits<TType>::ValueType>>,
TType >::Type
GetComponent(const TType pix,
unsigned int itkNotUsed( idx ) ) const
{
return pix;
}
\endcode
* \sa \c EnableIfC
* \sa \c DisableIf
*/
template <class TCondition, class TType = void>
struct DisableIf : public DisableIfC<TCondition::Value, TType>
{};

} // namespace mpl

// itk::EnableIf(C), DisableIf(C) have move to itk::mpl
// Expect them to be deprecated.
using mpl::EnableIf;
using mpl::DisableIf;
using mpl::EnableIfC;
using mpl::DisableIfC;

/// \endcond
} // namespace itk

#else // ITK_LEGACY_REMOVE
# error Use C++ 11 std::enable_if directly
#endif
// This file is no longer needed, features are natively available in C++11
#error Use C++ 11 std::enable_if directly

#endif // itkEnableIf_h
35 changes: 1 addition & 34 deletions Modules/Core/Common/include/itkIsBaseOf.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,6 @@
#ifndef itkIsBaseOf_h
#define itkIsBaseOf_h

#include <type_traits>

#include "itkMacro.h"

#if !defined(ITK_LEGACY_REMOVE)

namespace itk
{
/// \cond HIDE_META_PROGRAMMING
namespace mpl
{
/** Traits that emulates \c std::is_base_of<>.
* \tparam TBase base type
* \tparam TDerived derived type
* \return (in \c Value) whether \c TDerived inherits (publicly) from \c TBase
* (directly, or indirectly)
* \author The definition provided follows the code snippet available in Andrei
* Alexandrescu's <em>Modern C++ Design</em>.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <typename TBase, typename TDerived>
struct IsBaseOf
{
static constexpr bool Value = std::is_base_of_v<const TDerived *, const TBase *>;
};
} // end namespace mpl

/// \endcond
} // end namespace itk

#else // ITK_LEGACY_REMOVE
# error Use C++ 11 std::is_base_of directly
#endif
#error Use C++ 11 std::is_base_of directly

#endif // itkIsBaseOf_h
72 changes: 2 additions & 70 deletions Modules/Core/Common/include/itkIsConvertible.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,75 +17,7 @@
*=========================================================================*/
#ifndef itkIsConvertible_h
#define itkIsConvertible_h

#include "itkMacro.h"

#if !defined(ITK_LEGACY_REMOVE)

# include "itkMetaProgrammingLibrary.h"

namespace itk
{

/** \cond HIDE_META_PROGRAMMING */

namespace mpl
{
namespace Details
{

/** Helper root class for Meta-programming purpose.
* This class provides two types that help build SFINAE based meta-programs.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
struct SfinaeTypes
{
using TOne = char;
struct TTwo
{
char arr__[2];
};
};
} // namespace Details

/** Traits that emulates \c std::is_convertible<>.
* \tparam TFrom type to convert from
* \tparam TTo type to convert to
* \return (in \c Value) whether \c TFrom objects can be converted into \c TTo
* objects.
* \warning This version does not support \c void, function pointers, nor arrays.
* \author The definition provided follows the code snippet available in Andrei
* Alexandrescu's <em>Modern C++ Design</em>.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <typename TFrom, typename TTo>
struct IsConvertible : private Details::SfinaeTypes
{
private:
static TOne Test(TTo);
static TTwo
Test(...);
static TFrom
MakeT();

public:
static constexpr bool Value = sizeof(Test(MakeT())) == sizeof(TOne);
};

} // end namespace mpl

// itk::IsConvertible has moved to itk::mpl.
// Expect itk::IsConvertible to be deprecated.
using mpl::IsConvertible;

/** \endcond */

} // end namespace itk

#else // ITK_LEGACY_REMOVE
# error Use C++ 11 std::is_convertible directly
#endif
// This file is no longer needed, C++11 provides support directly
#error Use C++ 11 std::is_convertible directly

#endif // itkIsConvertible_h
41 changes: 2 additions & 39 deletions Modules/Core/Common/include/itkIsSame.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,7 @@
#ifndef itkIsSame_h
#define itkIsSame_h

#include "itkMacro.h"

#if !defined(ITK_LEGACY_REMOVE)

# include "itkMetaProgrammingLibrary.h"

namespace itk
{
/// \cond HIDE_META_PROGRAMMING
namespace mpl
{

/** Tells whether two types are identical.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <typename, typename>
struct IsSame : public FalseType
{};

/// \cond SPECIALIZATION_IMPLEMENTATION
template <typename T>
struct IsSame<T, T> : public TrueType
{};
/// \endcond

} // end namespace mpl

// itk::IsSame have move to itk::mpl
// Expect them to be deprecated.
using mpl::IsSame;

/// \endcond

} // end namespace itk

#else // ITK_LEGACY_REMOVE
# error Use C++ 11 std::is_same directly
#endif
// This file is no longer needed, C++11 provides support directly
#error Use C++ 11 std::is_same directly

#endif // itkIsSame_h
15 changes: 2 additions & 13 deletions Modules/Core/Common/include/itkStaticAssert.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,8 @@
#ifndef itkStaticAssert_h
#define itkStaticAssert_h

#include "itkMacro.h"

#if !defined(ITK_LEGACY_REMOVE)
/** Static assertion.
* This macro will use C++11 \c static_assert() keyword.
* \param expr compile-time expression to check
* \param str string literal that will appear as compiler error if \c expr is \c false.
* \ingroup ITKCommon
*/
# define itkStaticAssert(expr, str) static_assert(expr, str)
#else
# define itkStaticAssert(expr, str) Use C++ 11 static_assert directly
#endif
// This is no longer needed as C++11 provides this support directly
#define itkStaticAssert(expr, str) static_assert(false, "Use C++ 11 static_assert directly")

// TODO: remove this file entirely in the future (e.g. with ITKv6)

Expand Down

0 comments on commit e148489

Please sign in to comment.