/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2018 Danny Robson */ #ifndef CRUFT_UTIL_TUPLE_INDEX_HPP #define CRUFT_UTIL_TUPLE_INDEX_HPP #include /////////////////////////////////////////////////////////////////////////// // the implementation of all the below must be standalone as they are a // potential building block in other algorithms and we can't be sure we // won't create a dependency loop somewhere. namespace util::tuple::index { /////////////////////////////////////////////////////////////////////////// template struct indices {}; /////////////////////////////////////////////////////////////////////////// template struct cat; //------------------------------------------------------------------------- template < size_t ...A, size_t ...B > struct cat< indices, indices > { using type = indices; }; //------------------------------------------------------------------------- template using cat_t = typename cat::type; /////////////////////////////////////////////////////////////////////////// namespace detail { template struct make_indices { using type = cat_t< typename make_indices::type, indices >; }; template <> struct make_indices<0> { using type = indices<>; }; }; //------------------------------------------------------------------------- // create a monotonically increasing index sequence over the range [0,N) template struct make_indices { using type = typename detail::make_indices::type; }; //------------------------------------------------------------------------- template using make_indices_t = typename make_indices::type; /////////////////////////////////////////////////////////////////////////// namespace detail { template struct make_reverse; template struct make_reverse< indices > { using type = cat_t< typename make_reverse>::type, indices >; }; template <> struct make_reverse< indices<> > { using type = indices<>; }; }; //------------------------------------------------------------------------- // create a montonically decreasing index sequence over the range (N-1, 0]. // // eg, make_reverse<3> is indices<3,2,1,0> template struct make_reverse { using type = typename detail::make_reverse< make_indices_t >::type; }; //------------------------------------------------------------------------- template using make_reverse_t = typename make_reverse::type; }; #endif