/*========================================================================= * * 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 ``. * \ingroup MetaProgrammingLibrary * \ingroup ITKCommon */ struct TrueType { using ValueType = bool; using Type = TrueType; static constexpr ValueType Value = true; operator ValueType() { return Value; } }; /** borrowed from ``. * \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 struct If; /// \cond SPECIALIZATION_IMPLEMENTATION template struct If { using Type = T1; }; template struct If { 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 struct OrC : TrueType {}; /// \cond SPECIALIZATION_IMPLEMENTATION template <> struct OrC : 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 struct Or : OrC { using Type = typename OrC::Type; }; /** MPL \c AND operator on constants. * \tparam VF1 First boolean expression * \tparam VF2 Second boolean expression * \ingroup MetaProgrammingLibrary * \ingroup ITKCommon */ template struct AndC : FalseType {}; /// \cond SPECIALIZATION_IMPLEMENTATION template <> struct AndC : 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 struct And : AndC { using Type = typename AndC::Type; }; /** MPL \c XOR operator on constants. * \tparam VF1 First boolean expression * \tparam VF2 Second boolean expression * \ingroup MetaProgrammingLibrary * \ingroup ITKCommon */ template struct XorC : FalseType {}; /// \cond SPECIALIZATION_IMPLEMENTATION template <> struct XorC : TrueType {}; template <> struct XorC : 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 struct Xor : XorC { using Type = typename XorC::Type; }; /** MPL \c NOT operator on constants. * \tparam VF boolean expression to negate * \ingroup MetaProgrammingLibrary * \ingroup ITKCommon */ template struct NotC : FalseType {}; /// \cond SPECIALIZATION_IMPLEMENTATION template <> struct NotC : TrueType {}; template <> struct NotC : 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 struct Not : NotC { using Type = typename NotC::Type; }; /** MPL type trait to check if type is a SmartPointer. */ template struct IsSmartPointer : FalseType {}; /// \cond SPECIALIZATION_IMPLEMENTATION template struct IsSmartPointer> : TrueType {}; template struct IsSmartPointer> : TrueType {}; /// \endcond /** MPL relational type trait to check if a static_cast conversion * exists. * * Identifies if "static_cast(TFromType)" can be done. */ template using is_static_castable = std::integral_constant || std::is_convertible_v>; } // 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