diff options
-rw-r--r-- | main-window/CMakeLists.txt | 2 | ||||
-rw-r--r-- | main-window/mixin-traits.cpp | 41 | ||||
-rw-r--r-- | main-window/mixin-traits.hpp | 41 |
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 |