diff --git a/include/utl/meta/bool.h b/include/utl/meta/bool.h new file mode 100755 index 0000000..1767115 --- /dev/null +++ b/include/utl/meta/bool.h @@ -0,0 +1,48 @@ +/*! + * \file bool.h + * \brief Template meta-programming bool integral constant + * + * Copyright (C) 2018 Christos Choutouridis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef __utl_meta_bool_h__ +#define __utl_meta_bool_h__ + +#include +#include + +/*! + * \ingroup meta + * \defgroup bool + * boolean constant type support header + */ +//! @{ + +namespace utl { + + //! bool_ type + template + using bool_ = integral_; + + //! The type used as a compile-time boolean with true value. + typedef bool_ true_; + + //! The type used as a compile-time boolean with false value. + typedef bool_ false_; + +} + +//! @} +#endif /* __utl_meta_bool_h__ */ diff --git a/include/utl/meta/if.h b/include/utl/meta/if.h new file mode 100755 index 0000000..db753d5 --- /dev/null +++ b/include/utl/meta/if.h @@ -0,0 +1,64 @@ +/*! + * \file if.h + * \brief Template meta-programming conditional helpers + * + * Copyright (C) 2018 Christos Choutouridis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef __utl_meta_if_h__ +#define __utl_meta_if_h__ + +#include + + +/*! + * \ingroup meta + * \defgroup if + * conditional type support header + */ +//! @{ +namespace utl { + + //! if_ + //! @{ + template + struct if_ { + typedef _T1 type; + }; + + template + struct if_ { + typedef _T2 type; + }; + //! @} + + //! enable_if + //! @{ + template + struct enable_if { }; + + // Partial specialization for true. + template + struct enable_if { + typedef _Tp type; + }; + //! Alias template for enable_if + template + using enable_if_t = typename enable_if<_C, _Tp>::type; + //! @} +} + +//! @} +#endif /* __utl_meta_if_h__ */ diff --git a/include/utl/meta/integral.h b/include/utl/meta/integral.h new file mode 100755 index 0000000..061b55f --- /dev/null +++ b/include/utl/meta/integral.h @@ -0,0 +1,54 @@ +/*! + * \file integral.h + * \brief Template meta-programming integral constant + * + * Copyright (C) 2018 Christos Choutouridis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef __utl_meta_integral_h__ +#define __utl_meta_integral_h__ + +#include + +/*! + * \ingroup meta + * \defgroup integral + * integral constand support header + */ +//! @{ + +namespace utl { + + //! integral_constant + template + struct integral_ { + using value_type = _Tp; + using type = integral_<_Tp, _v>; + + constexpr operator value_type() const { + return value; + } + constexpr value_type operator()() const { + return value; + } + static constexpr _Tp value = _v; + }; + + template + constexpr _Tp integral_<_Tp, _v>::value; +} +//!@} + +#endif /* __utl_meta_integral_h__ */ diff --git a/include/utl/meta/logical.h b/include/utl/meta/logical.h new file mode 100755 index 0000000..a5f3d0d --- /dev/null +++ b/include/utl/meta/logical.h @@ -0,0 +1,100 @@ +/*! + * \file logical.h + * \brief Template meta-programming logic operator and type relations. + * + * Copyright (C) 2018 Christos Choutouridis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef __utl_meta_logical_h__ +#define __utl_meta_logical_h__ + +#include +#include +#include + +/*! + * \ingroup meta + * \defgroup logic + * logic operator and type relations support header + */ +//! @{ +namespace utl { + + //! NOT implementation + template + struct not_ : bool_ { }; + + //! OR implementation + //! @{ + template struct or_; + + template<> + struct or_<> + : false_ { }; + + template + struct or_<_T1> + : _T1 { }; + + template + struct or_ <_T1, _T2> + : if_<_T1::value, _T1, _T2>::type { }; + + template + struct or_<_T1, _T2, _T3, _Tn...> + : if_<_T1::value, _T1, or_<_T2, _T3, _Tn...>>::type { }; + //! @} + + //! AND implementation + //! @{ + template struct and_; + + template<> + struct and_<> + : true_ { }; + + template + struct and_ <_T1> + : _T1 { }; + + template + struct and_<_T1, _T2> + : if_<_T1::value, _T2, _T1>::type { }; + + template + struct and_<_T1, _T2, _T3, _Tn...> + : if_<_T1::value, and_<_T2, _T3, _Tn...>, _T1>::type { }; + //! @} + + //! same + //! @{ + template + struct same_ : false_ { }; + + template + struct same_ <_Tp, _Tp> : true_ { }; + //! @} + + //! not same + //! @{ + template + struct not_same_ : true_ { }; + + template + struct not_same_ <_Tp, _Tp> : false_ { }; + //! @} +} + +#endif /* __utl_meta_logical_h__ */ diff --git a/include/utl/meta/sfinae.h b/include/utl/meta/sfinae.h new file mode 100755 index 0000000..d611685 --- /dev/null +++ b/include/utl/meta/sfinae.h @@ -0,0 +1,64 @@ +/*! + * \file use.h + * \brief Template meta-programming SFINAE helpers + * + * Copyright (C) 2018 Christos Choutouridis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef __utl_meta_use_h__ +#define __utl_meta_use_h__ + +#include +#include + + +/*! + * \ingroup meta + * \defgroup use + * conditional use support header. This is a SFINAE helper + */ +//! @{ +namespace utl { + + //! If same type resolves to _Ret, else to SFINAE + //! @{ + template + struct use_if_same_ { + using type = enable_if_t < + same_<_Tp1, _Tp2>::value, + _Ret + >; + }; + template + using use_if_same_t = typename use_if_same_<_Tp1, _Tp2, _Ret>::type; + //! @} + + //! If same type resolves to SFINAE, else to _Ret + //! @{ + template + struct discard_if_same_ { + using type = enable_if_t < + !same_<_Tp1, _Tp2>::value, + _Ret + >; + }; + template + using discard_if_same_t = typename discard_if_same_<_Tp1, _Tp2, _Ret>::type; + //! @} + +} + +//! @} +#endif /* __utl_meta_use_h__ */ diff --git a/include/utl/meta/void.h b/include/utl/meta/void.h new file mode 100755 index 0000000..b5df113 --- /dev/null +++ b/include/utl/meta/void.h @@ -0,0 +1,63 @@ +/*! + * \file void.h + * \brief Template meta-programming void helpers + * + * Copyright (C) 2018 Christos Choutouridis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef __utl_meta_void_h__ +#define __utl_meta_void_h__ + +#include +#include + +/*! \ingroup meta + * \defgroup void + * void_ support header + */ +//! @{ + +namespace utl { + + /*! + * Like boost::mpl we made void_ a complete type to allow it to be + * instantiated so that it can be passed in as an object that can be + * used to select an overloaded function. + */ + struct void_ { + typedef void_ type; + }; + + template + struct is_void_ + : false_ { }; + + template<> + struct is_void_ + : true_ { }; + + template + struct is_not_void_ + : true_ { }; + + template<> + struct is_not_void_ + : false_ { }; + +} + +//!@} + +#endif /* __utl_meta_void_h__ */ diff --git a/include/utl/meta/void_t.h b/include/utl/meta/void_t.h new file mode 100755 index 0000000..523fd1c --- /dev/null +++ b/include/utl/meta/void_t.h @@ -0,0 +1,52 @@ +/*! + * \file void_t.h + * \brief Template meta-programming helpers + * + * Copyright (C) 2018 Christos Choutouridis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef __utl_meta_void_t_h__ +#define __utl_meta_void_t_h__ + +#include + +//! \ingroup meta +//! \defgroup void_t +//! A void_t implementation for utl +//! @{ +namespace utl { + + /*! + * Utility meta-function that maps a sequence of any types to the type void + * \note The idea is: + * template + * using void_t = void; + * + * Until CWG 1558 (a C++14 defect), unused parameters in alias templates were not + * guaranteed to ensure SFINAE and could be ignored, so earlier compilers require + * a more complex definition of void_t, such as the following implementation + * https://en.cppreference.com + */ + template + struct void_impl { + typedef void type; + }; + //! The actual void_t type alias + template + using void_t = typename void_impl<_Ts...>::type; +} +//! @} + +#endif /* __utl_meta_void_t_h__ */