summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--main-window/CMakeLists.txt2
-rw-r--r--main-window/mixin-traits.cpp41
-rw-r--r--main-window/mixin-traits.hpp41
3 files changed, 53 insertions, 31 deletions
diff --git a/main-window/CMakeLists.txt b/main-window/CMakeLists.txt
index 3edd241b..f69080f1 100644
--- a/main-window/CMakeLists.txt
+++ b/main-window/CMakeLists.txt
@@ -1,4 +1,4 @@
-otr_module(main-window BIN)
+otr_module(main-window BIN NO-INSTALL)
foreach(k user-interface logic pose-widget migration spline)
target_link_libraries(${self} opentrack-${k})
endforeach()
diff --git a/main-window/mixin-traits.cpp b/main-window/mixin-traits.cpp
index ea8e9bc8..5dc2efd8 100644
--- a/main-window/mixin-traits.cpp
+++ b/main-window/mixin-traits.cpp
@@ -1,22 +1,27 @@
-//#define MIXIN_TRAIT_TESTS
+#define MIXIN_TRAIT_TESTS
#ifdef MIXIN_TRAIT_TESTS
# include "mixin-traits.hpp"
+// the `impl' class provides a cast template through the CRTP pattern.
+// mixins don't do direct inheritance on themselves,
+// that's what mixin_traits::depends is for.
+
namespace mixins::traits_detail {
struct A {};
-struct B : A {};
+struct B {};
struct C {};
+struct D {};
-template<> struct mixin_traits<B>
+template<> struct mixin_traits<A>
{
- using depends = tuple<A>;
+ using depends = tuple<>;
};
-template<> struct mixin_traits<A>
+template<> struct mixin_traits<B>
{
- using depends = tuple<>;
+ using depends = tuple<A>;
};
template<> struct mixin_traits<C>
@@ -24,13 +29,31 @@ template<> struct mixin_traits<C>
using depends = tuple<A>;
};
+template<> struct mixin_traits<D>
+{
+ using depends = tuple<C>;
+};
+
extern void test1();
void test1()
{
- //impl<C> fail1;
- impl<B> ok1;
- impl<A> ok2;
+ struct U : B, A {};
+ struct V : D {};
+ struct W : C, A {};
+ struct Q : virtual W, virtual D {};
+
+#if 0
+ (void)impl<Q, W>(); // W not a mixin
+ (void)impl<V, A>(); // A
+ (void)impl<V, D>(); // D => C => A
+ (void)impl<V, D>(); // D => C => A
+ (void)impl<W, C, B>(); // B
+#else
+ (void)impl<U, B>();
+ (void)impl<W, C>();
+ (void)impl<Q, D, A>();
+#endif
}
} // ns mixins::traits_detail
diff --git a/main-window/mixin-traits.hpp b/main-window/mixin-traits.hpp
index 84a64d08..6a0206fc 100644
--- a/main-window/mixin-traits.hpp
+++ b/main-window/mixin-traits.hpp
@@ -1,7 +1,5 @@
#pragma once
-#include "compat/linkage-macros.hpp"
-#include "compat/macros.hpp"
#include "compat/meta.hpp"
#include <type_traits>
@@ -9,40 +7,41 @@
namespace mixins::traits_detail {
using namespace meta;
- template<typename... xs>
- using tuple = meta::detail::tuple<xs...>;
+
+ template<typename... xs> using tuple = tuple_<xs...>;
template<typename t>
struct mixin_traits {
- //using depends = tuple<>;
+ // implement this!
+ using depends = tuple<>;
+
+ // unconditional but at instantiation time
+ static_assert(sizeof(t) < sizeof(char),
+ "must specialize mixin_traits");
};
template<typename klass, typename...> struct check_depends_;
template<typename klass>
- struct check_depends_<klass>
+ struct check_depends_<klass> : std::true_type
{
- using type = std::bool_constant<true>;
};
template<typename klass, typename x, typename... xs>
- struct check_depends_<klass, x, xs...>
+ struct check_depends_<klass, x, xs...> :
+ std::bool_constant<
+ std::is_base_of_v<x, klass> &&
+ lift<check_depends_, cons<klass, typename mixin_traits<x>::depends>>::value &&
+ check_depends_<klass, xs...>::value
+ >
{
- using b1 = std::is_base_of<x, klass>;
- using b2 = typename check_depends_<klass, xs...>::type;
-
- using depends = typename mixin_traits<x>::depends;
- using t1 = cons<klass, depends>;
- using t2 = lift<check_depends_, t1>;
- using b3 = typename t2::type;
-
- using type = std::bool_constant<b1::value && b2::value && b3::value>;
};
- template<typename t>
- class impl
+ template<typename klass, typename... xs>
+ struct impl
{
- using t1 = typename lift<check_depends_, cons<t, typename mixin_traits<t>::depends>>::type;
- static_assert(t1::value);
+ static constexpr bool class_must_inherit_dependent_mixins =
+ lift<check_depends_, tuple<klass, xs...>>::value;
+ static_assert(class_must_inherit_dependent_mixins);
};
} // ns mixins::traits_detail