1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
/*=========================================================================
*
* 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.
*
*=========================================================================*/
#ifndef itkMetaProgrammingLibrary_h
#define itkMetaProgrammingLibrary_h
#include "itkMacro.h"
#include "itkSmartPointer.h"
namespace itk
{
/// \cond HIDE_META_PROGRAMMING
namespace mpl
{
/**\defgroup MetaProgrammingLibrary Meta Programming Library
* This module contains definitions aimed at metaprogramming.
* They are mainly codes borrowed or inspired from C++11 or indirectly boost,
* with ITK UpperCamelCase naming policy.
*/
/** borrowed from `<type_traits>`.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
struct TrueType
{
using ValueType = bool;
using Type = TrueType;
static constexpr ValueType Value = true;
operator ValueType() { return Value; }
};
/** borrowed from `<type_traits>`.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
struct FalseType
{
using ValueType = bool;
using Type = FalseType;
static constexpr ValueType Value = false;
operator ValueType() { return Value; }
};
/** MPL \c if control-statement.
* \tparam VP Boolean predicate
* \tparam T1 Type returned if the predicate is true
* \tparam T2 Type returned if the predicate is false
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <bool VP, typename T1, typename T2>
struct If;
/// \cond SPECIALIZATION_IMPLEMENTATION
template <typename T1, typename T2>
struct If<true, T1, T2>
{
using Type = T1;
};
template <typename T1, typename T2>
struct If<false, T1, T2>
{
using Type = T2;
};
/// \endcond
/** MPL \c OR operator on constants.
* \tparam VF1 First boolean expression
* \tparam VF2 Second boolean expression
* \tparam VF3 Third (optional) boolean expression
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <bool VF1, bool VF2, bool VF3 = false>
struct OrC : TrueType
{};
/// \cond SPECIALIZATION_IMPLEMENTATION
template <>
struct OrC<false, false, false> : FalseType
{};
/// \endcond
/** MPL \c OR operator on types.
* \tparam TF1 First boolean type
* \tparam TF2 Second boolean type
* \tparam VF3 Third (optional) boolean type
*
* This \em overload automatically fetches \c TF1, \c TF2 and \c TF3 values.
* However, beware, it won't work with standard C++ traits or boost traits.
* Indeed, this overload expects the \em value to follow UpperCamelCase ITK
* naming policy instead of the standard snake_case policy.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <typename TF1, typename TF2, typename TF3 = FalseType>
struct Or : OrC<TF1::Value, TF2::Value, TF3::Value>
{
using Type = typename OrC<TF1::Value, TF2::Value, TF3::Value>::Type;
};
/** MPL \c AND operator on constants.
* \tparam VF1 First boolean expression
* \tparam VF2 Second boolean expression
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <bool VF1, bool VF2>
struct AndC : FalseType
{};
/// \cond SPECIALIZATION_IMPLEMENTATION
template <>
struct AndC<true, true> : TrueType
{};
/// \endcond
/** MPL \c AND operator on types.
* \tparam TF1 First boolean type
* \tparam TF2 Second boolean type
*
* This \em overload automatically fetches \c TF1 and \c TF2 values.
* However, beware, it won't work with standard C++ traits or boost traits.
* Indeed, this overload expects the \em value to follow UpperCamelCase ITK
* naming policy instead of the standard snake_case policy.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <typename TF1, typename TF2>
struct And : AndC<TF1::Value, TF2::Value>
{
using Type = typename AndC<TF1::Value, TF2::Value>::Type;
};
/** MPL \c XOR operator on constants.
* \tparam VF1 First boolean expression
* \tparam VF2 Second boolean expression
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <bool VF1, bool VF2>
struct XorC : FalseType
{};
/// \cond SPECIALIZATION_IMPLEMENTATION
template <>
struct XorC<true, false> : TrueType
{};
template <>
struct XorC<false, true> : TrueType
{};
/// \endcond
/** MPL \c XOR operator on types.
* \tparam TF1 First boolean type
* \tparam TF2 Second boolean type
*
* This \em overload automatically fetches \c TF1 and \c TF2 values.
* However, beware, it won't work with standard C++ traits or boost traits.
* Indeed, this overload expects the \em value to follow UpperCamelCase ITK
* naming policy instead of the standard snake_case policy.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <typename TF1, typename TF2>
struct Xor : XorC<TF1::Value, TF2::Value>
{
using Type = typename XorC<TF1::Value, TF2::Value>::Type;
};
/** MPL \c NOT operator on constants.
* \tparam VF boolean expression to negate
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <bool VF>
struct NotC : FalseType
{};
/// \cond SPECIALIZATION_IMPLEMENTATION
template <>
struct NotC<false> : TrueType
{};
template <>
struct NotC<true> : FalseType
{};
/// \endcond
/** MPL \c NOT operator on types.
* \tparam TF Second boolean type
*
* This \em overload automatically fetches \c TF value.
* However, beware, it won't work with standard C++ traits or boost traits.
* Indeed, this overload expects the \em value to follow UpperCamelCase ITK
* naming policy instead of the standard snake_case policy.
* \ingroup MetaProgrammingLibrary
* \ingroup ITKCommon
*/
template <typename TF>
struct Not : NotC<TF::Value>
{
using Type = typename NotC<TF::Value>::Type;
};
/** MPL type trait to check if type is a SmartPointer.
*/
template <typename T>
struct IsSmartPointer : FalseType
{};
/// \cond SPECIALIZATION_IMPLEMENTATION
template <typename T>
struct IsSmartPointer<SmartPointer<T>> : TrueType
{};
template <typename T>
struct IsSmartPointer<const SmartPointer<T>> : TrueType
{};
/// \endcond
/** MPL relational type trait to check if a static_cast conversion
* exists.
*
* Identifies if "static_cast<TToType>(TFromType)" can be done.
*/
template <typename TFromType, typename TToType>
using is_static_castable =
std::integral_constant<bool,
std::is_constructible_v<TToType, TFromType> || std::is_convertible_v<TFromType, TToType>>;
} // namespace mpl
// TrueType and FalseType have moved to itk::mpl.
// Expect itk::TrueType and itk::False type to be deprecated.
using mpl::TrueType;
using mpl::FalseType;
/// \endcond
} // namespace itk
#endif // itkMetaProgrammingLibrary_h
|