1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 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 #ifndef itkEnableIf_h 19 #define itkEnableIf_h 20 21 namespace itk 22 { 23 /// \cond HIDE_META_PROGRAMMING 24 namespace mpl 25 { 26 27 /** \brief This is an implementation of the enable if idiom. 28 * \ingroup MetaProgrammingLibrary 29 * \ingroup ITKCommon 30 * 31 * Enable if is a common C++ meta-programming technique for example 32 * there is a boost implementation, for more information on its usage 33 * please see: 34 * http://www.boost.org/doc/libs/1_49_0/libs/utility/enable_if.html 35 * 36 * This template enables specialization of a templated function based 37 * on some traits or concepts. It is implemented with SFINAE. 38 * 39 * If the parameter V is true then the Type trait is the second 40 * template parameter, otherwise an implementation does not exist and 41 * with SFINAE another implementation may be choosen. 42 * 43 * Example: 44 \code 45 template< typename TType> 46 typename EnableIfC< 47 IsSame<TType, typename NumericTraits<TType>::ValueType>::Value, 48 TType >::Type 49 GetComponent(const TType pix, 50 unsigned int itkNotUsed( idx ) ) const 51 { 52 return pix; 53 } 54 \endcode 55 * 56 * \sa \c EnableIf 57 */ 58 template <bool V, typename TType = void> struct EnableIfC {}; 59 /// \cond SPECIALIZATION_IMPLEMENTATION 60 template <typename TType> struct EnableIfC<true, TType> { using Type = TType; }; 61 /// \endcond 62 63 64 /** \brief An implementation of the negation of the enable if idiom. 65 * \ingroup MetaProgrammingLibrary 66 * \ingroup ITKCommon 67 * 68 * \sa \c EnableIfC 69 * \sa \c DisableIf 70 */ 71 template <bool V, typename TType = void> struct DisableIfC {}; 72 /// \cond SPECIALIZATION_IMPLEMENTATION 73 template <typename TType> struct DisableIfC<false, TType> { using Type = TType; }; 74 /// \endcond 75 76 /** \brief simplified way to dispose of \c enable_if. 77 * \ingroup MetaProgrammingLibrary 78 * \ingroup ITKCommon 79 * \tparam TCondition Condition type. It's expected to provide a boolean value 80 * through its \c Value member. 81 * \tparam TType Type to \em return when the \c TCondition is (a) true (type). 82 * 83 * This \em overload automatically fetches \c TCondition value. However, beware, it 84 * won't work with standard C++ traits or boost traits. Indeed, this \c 85 * enable_if overload expects the \em value to follow UpperCamelCase ITK naming 86 * policy instead of the standard snake_case policy. 87 * 88 * Example: 89 \code 90 template< typename TType> 91 typename EnableIf< 92 IsSame<TType, typename NumericTraits<TType>::ValueType>, 93 TType >::Type 94 GetComponent(const TType pix, 95 unsigned int itkNotUsed( idx ) ) const 96 { 97 return pix; 98 } 99 \endcode 100 * \sa \c EnableIfC 101 * \sa \c DisableIf 102 */ 103 template <class TCondition, class TType = void> 104 struct EnableIf : public EnableIfC<TCondition::Value, TType> {}; 105 106 /** \brief simplified way to dispose of \c disable_if. 107 * \ingroup MetaProgrammingLibrary 108 * \ingroup ITKCommon 109 * \tparam TCondition Condition type. It's expected to provide a boolean value 110 * through its \c Value member. 111 * \tparam TType Type to \em return when the \c TCondition is (a) false (type). 112 * 113 * This \em overload automatically fetches \c TCondition value. However, beware, it 114 * won't work with standard C++ traits or boost traits. Indeed, this \c 115 * enable_if overload expects the \em value to follow UpperCamelCase ITK naming 116 * policy instead of the standard snake_case policy. 117 * 118 * Example: 119 \code 120 template< typename TType> 121 typename DisableIf< 122 mpl::Not_<IsSame<TType, typename NumericTraits<TType>::ValueType>>, 123 TType >::Type 124 GetComponent(const TType pix, 125 unsigned int itkNotUsed( idx ) ) const 126 { 127 return pix; 128 } 129 \endcode 130 * \sa \c EnableIfC 131 * \sa \c DisableIf 132 */ 133 template <class TCondition, class TType = void> 134 struct DisableIf : public DisableIfC<TCondition::Value, TType> {}; 135 136 } // namespace itk::mpl 137 138 // itk::EnableIf(C), DisableIf(C) have move to itk::mpl 139 // Expect them to be deprecated. 140 using mpl::EnableIf; 141 using mpl::DisableIf; 142 using mpl::EnableIfC; 143 using mpl::DisableIfC; 144 145 /// \endcond 146 } // namespace itk 147 148 #endif // itkEnableIf_h 149