summaryrefslogtreecommitdiffhomepage
path: root/compat/meta.hpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2017-04-29 16:05:09 +0200
committerStanislaw Halik <sthalik@misaki.pl>2017-04-29 16:05:18 +0200
commitef7a777660034a142f24a5edc63d06f25d4d0562 (patch)
tree25783296bdf2c2ff08bde2e64072ca85e4e8942d /compat/meta.hpp
parent057cf55a2a24477251fc947db6981fc8f1a6cfe6 (diff)
compat/meta: add basic template metaprogramming header
Diffstat (limited to 'compat/meta.hpp')
-rw-r--r--compat/meta.hpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/compat/meta.hpp b/compat/meta.hpp
new file mode 100644
index 00000000..b1c1dd1a
--- /dev/null
+++ b/compat/meta.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <tuple>
+
+namespace meta {
+
+namespace detail {
+
+ template<typename x, typename y>
+ 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 inst, typename x>
+ struct lift_;
+
+ template<template<typename...> class inst, template<typename...> class x, typename... xs>
+ struct lift_<inst, x<xs...>>
+ {
+ using type = inst<xs...>;
+ };
+}
+
+
+template<typename... xs>
+using reverse = typename detail::reverse_<std::tuple<xs...>, std::tuple<>>::type;
+
+template<template<typename...> class inst, class x>
+using lift = typename detail::lift_<inst, x>::type;
+
+template<typename x, typename... xs>
+using first = x;
+
+template<typename x, typename... xs>
+using rest = std::tuple<xs...>;
+
+template<typename... xs>
+using butlast = reverse<rest<reverse<xs...>>>;
+
+template<typename... xs>
+using last = lift<first, reverse<xs...>>;
+
+}