Loading...
Searching...
No Matches
SubtypeVariant.hpp
1#pragma once
2#include <ossia/detail/variant.hpp>
3
4#include <boost/mp11/algorithm.hpp>
5
6#include <type_traits>
7
8namespace score
9{
10namespace detail
11{
16template <typename T>
18{
19 const T& impl;
20
21 template <typename Arg>
22 auto operator()(Arg&& arg) const
23 {
24 return impl(*std::forward<Arg>(arg));
25 }
26
27 auto operator()() const { return impl(); }
28};
29
30template <typename Variant, typename Base>
31Variant make_subtype_variant(const Base&)
32{
33 // The type does not match any
34 // in the proposed types for the variant.
35 return Variant{};
36}
37
38template <typename Variant, typename Base, typename Arg, typename... SubArgs>
39Variant make_subtype_variant(Base& base)
40{
41 if(auto derived = dynamic_cast<Arg*>(&base))
42 {
43 return Variant(derived);
44 }
45
46 return make_subtype_variant<Variant, Base, SubArgs...>(base);
47}
48
49template <typename Variant, typename Base, typename Arg, typename... SubArgs>
50Variant make_subtype_variant(const Base& base)
51{
52 if(auto derived = dynamic_cast<const Arg*>(&base))
53 {
54 return Variant(derived);
55 }
56
57 return make_subtype_variant<Variant, Base, SubArgs...>(base);
58}
59}
60
70template <typename Base, typename... Args>
72{
73 using arg_list = ossia::variant<Args...>;
74 using ptr_list = boost::mp11::mp_transform<std::add_pointer_t, arg_list>;
75
76 ptr_list m_impl;
77
78public:
79 explicit SubtypeVariant(Base& b)
80 : m_impl(detail::make_subtype_variant<ptr_list, Base, Args...>(b))
81 {
82 }
83
84 explicit SubtypeVariant(const Base& b)
85 : m_impl(detail::make_subtype_variant<ptr_list, Base, Args...>(b))
86 {
87 }
88
89 template <typename F>
90 auto apply(F&& f)
91 {
92 if(m_impl)
93 {
94 return ossia::visit(detail::dereference_visitor<F>{f}, m_impl);
95 }
96 else
97 {
99 }
100 }
101};
102}
Tools to build a variant type from classes in a same hierarchy.
Definition SubtypeVariant.hpp:72
Base toolkit upon which the software is built.
Definition Application.cpp:97
Proxy visitor that dereferences before calling the actual visitor.
Definition SubtypeVariant.hpp:18