/* * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. * * 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