#pragma once /* Copyright (c) 2017 Stanislaw Halik * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ #define OTR_META_INST_FAIL(x) \ static_assert(sizeof...(x) == ~0ul); \ static_assert(sizeof...(x) == 0u) namespace meta::detail { template struct tuple; template struct reverse_ { OTR_META_INST_FAIL(xs); }; template class x, typename... ys> struct reverse_, x> { using type = typename reverse_, x>::type; }; template class x, typename... ys> struct reverse_, x> { using type = x; }; template class inst, typename... xs> struct lift_ { OTR_META_INST_FAIL(xs); }; template class to, template class from, typename... xs> struct lift_> { using type = to; }; template struct cons_; template class t, typename x, typename... xs> struct cons_, x> { using type = t; }; } // ns meta::detail namespace meta { template using reverse = typename detail::reverse_, detail::tuple<>>::type; // the to/from order is awkward but mimics function composition template class to, typename from> using lift = typename detail::lift_::type; template using first = x; template using rest = detail::tuple; template using butlast = reverse>>; template using last = lift>; template using cons = detail::cons_; } // ns meta