diff options
Diffstat (limited to 'compat/meta.hpp')
| -rw-r--r-- | compat/meta.hpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/compat/meta.hpp b/compat/meta.hpp new file mode 100644 index 00000000..49686996 --- /dev/null +++ b/compat/meta.hpp @@ -0,0 +1,123 @@ +#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. + */ + +namespace meta::detail { + + template<typename... xs> + struct tuple; + + template<typename... xs> + struct reverse_; + + template<typename x0, typename... xs, template<typename...> class x, typename... ys> + struct reverse_<x<x0, xs...>, x<ys...>> + { + using type = typename reverse_<x<xs...>, x<x0, ys...>>::type; + }; + + template<template<typename...> class x, typename... ys> + struct reverse_<x<>, x<ys...>> + { + using type = x<ys...>; + }; + + template<template<typename...> class, typename, typename...> struct lift_; + + template<template<typename...> class to, template<typename...> class from, typename... xs> + struct lift_<to, from<xs...>> + { + using type = to<xs...>; + }; + + template<typename> struct append_helper; + + template<typename, typename> struct cons_; + + template<typename x, template<typename...> class t, typename... xs> + struct cons_<x, t<xs...>> + { + using type = t<x, xs...>; + }; + + template<typename> struct append2; + + template<template<typename...> class t, typename... xs> + struct append2<t<xs...>> + { + template<typename> struct append1; + + template<template<typename...> class u, typename... ys> + struct append1<u<ys...>> + { + using type = t<xs..., ys...>; + }; + }; + + template<typename, typename...> struct list__; + + template<typename rest, typename... first> + struct list__ + { + template<typename> struct list1; + + template<template<typename...> class t, typename... xs> + struct list1<t<xs...>> + { + using type = t<first..., xs...>; + }; + + using type = typename list1<rest>::type; + }; + + template<typename xs, typename ys> + struct append_ + { + using t1 = append2<xs>; + using type = typename t1::template append1<ys>::type; + }; + +} // ns meta::detail + +namespace meta { + template<typename... xs> + using tuple_ = detail::tuple<xs...>; + + template<typename... xs> + using reverse = typename detail::reverse_<detail::tuple<xs...>, detail::tuple<>>::type; + + // the to/from order is awkward but mimics function composition + template<template<typename...> class to, typename from> + using lift = typename detail::lift_<to, from>::type; + + template<template<typename...> class to, typename from> + constexpr inline auto lift_v = detail::lift_<to, from>::type::value; + + template<typename x, typename... xs> + using first = x; + + template<typename x, typename... xs> + using rest = detail::tuple<xs...>; + + template<typename... xs> + using butlast = reverse<rest<reverse<xs...>>>; + + template<typename... xs> + using last = lift<first, reverse<xs...>>; + + template<typename x, typename rest> + using cons = typename detail::cons_<x, rest>::type; + + template<typename xs, typename ys> + using append = typename detail::append_<xs, ys>; + + template<typename rest, typename... xs> + using list_ = typename detail::list__<rest, xs...>; + +} // ns meta + |
