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