/*! * \file pack.h * \brief Template meta-programming parameter pack container * * Copyright (C) 2018-2019 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_idx_sequence_h__ #define __utl_meta_idx_sequence_h__ #include #include /*! * \ingroup meta * \defgroup index_sequence */ //! @{ namespace utl { namespace meta { /*! * Class template integer_sequence */ template struct integer_sequence { using value_type = _Tp; static constexpr size_t size() noexcept { return sizeof...(_Idx); } }; //! Alias template index_sequence template using index_sequence = integer_sequence; //! make_integer_sequence //! @{ namespace detail { // Stores a tuple of indices template struct index_tuple { }; // Concatenates two index_tuples. template struct it_cat_; template struct it_cat_ , index_tuple> { using type = index_tuple; }; // Builds an index_tuple<0, 1, 2, ..., _Num-1>. template struct make_index_tuple_ : it_cat_>, eval>> { }; // termination specialization for 1 template<> struct make_index_tuple_<1> { using type = index_tuple<0>; }; // termination specialization for 0 template<> struct make_index_tuple_<0> { using type = index_tuple<>; }; // factory type template>> struct make_integer_sequence_; template struct make_integer_sequence_<_Tp, _Num, index_tuple<_Idx...>> { static_assert( _Num >= 0, "Cannot make integer sequence of negative length" ); using type = integer_sequence<_Tp, static_cast<_Tp>(_Idx)...>; }; } //! Alias template make_integer_sequence //! Complexity \f$ O(log N) \f$ template using make_integer_sequence = eval>; //! Alias template make_index_sequence //! Complexity \f$ O(log N) \f$ template using make_index_sequence = make_integer_sequence; //! Alias template index_sequence_for //! Complexity \f$ O(log N) \f$ //! where N is sizeof...(_Ts) template using index_sequence_for = make_index_sequence; //! @} }} //! @} #endif /* __utl_meta_idx_sequence_h__ */