Turi Create  4.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
toolkit_class_wrapper_impl.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_UNITY_TOOLKIT_CLASS_WRAPPER_IMPL_HPP
7 #define TURI_UNITY_TOOLKIT_CLASS_WRAPPER_IMPL_HPP
8 #include <model_server/lib/toolkit_function_wrapper_impl.hpp>
9 
10 namespace turi {
11 class model_base;
12 namespace toolkit_class_wrapper_impl {
13 using turi::toolkit_function_wrapper_impl::generate_member_function_wrapper;
14 using turi::toolkit_function_wrapper_impl::generate_const_member_function_wrapper;
15 
16 /**
17  * Wraps a member function T::f(...) with a function that takes a
18  * variant_map_type and returns a variant_type.
19  * Essentially, given a function f of type ret(in1, in2, in3 ...),
20  * returns a function g of type variant_type(variant_map_type) where g
21  * performs the equivalent of:
22  *
23  * \code
24  * variant_type g(T* t, variant_map_type input) {
25  * return variant_encode( t->f (variant_decode(input[inargnames[0]),
26  * variant_decode(input[inargnames[1]),
27  * variant_decode(input[inargnames[2]),
28  * ...));
29  * }
30  *
31  * \endcode
32  * Performs the equivalent to
33  * toolkit_function_wrapper_impl::generate_member_function_wrapper but takes
34  * the inargnames argument as a varargs.
35  */
36 template <typename T, typename Ret, typename... Args, typename... VarArgs>
37 std::function<variant_type(model_base*, variant_map_type)>
38 generate_member_function_wrapper_indirect(Ret (T::* fn)(Args...), VarArgs... args) {
39  auto newfn = generate_member_function_wrapper<sizeof...(Args), T, Ret, Args...>(fn, {args...});
40  return [newfn](model_base* curthis, variant_map_type in)->variant_type {
41  return to_variant(newfn(dynamic_cast<T*>(curthis), in));
42  };
43 }
44 
45 
46 /**
47  * Wraps a member function T::f(...) const with a function that takes a
48  * variant_map_type and returns a variant_type.
49  * Essentially, given a function f of type ret(in1, in2, in3 ...),
50  * returns a function g of type variant_type(variant_map_type) where g
51  * performs the equivalent of:
52  *
53  * \code
54  * variant_type g(T* t, variant_map_type input) {
55  * return variant_encode( t->f (variant_decode(input[inargnames[0]),
56  * variant_decode(input[inargnames[1]),
57  * variant_decode(input[inargnames[2]),
58  * ...));
59  * }
60  *
61  * \endcode
62  *
63  * Performs the equivalent to toolkit_function_wrapper_impl::generate_const
64  * member_function_wrapper but takes the inargnames argument as a varargs.
65  *
66  * \note Overload of generate_member_function_wrapper_indirect to handle
67  * the const case even though the code is... *identical*. I can't figure out
68  * how to templatize around the const.
69  */
70 template <typename T, typename Ret, typename... Args, typename... VarArgs>
71 std::function<variant_type(model_base*, variant_map_type)>
72 generate_member_function_wrapper_indirect(Ret (T::* fn)(Args...) const, VarArgs... args) {
73  auto newfn = generate_const_member_function_wrapper<sizeof...(Args), T, Ret, Args...>(fn, {args...});
74  return [newfn](model_base* curthis, variant_map_type in)->variant_type {
75  return to_variant(newfn(dynamic_cast<T*>(curthis), in));
76  };
77 }
78 
79 /**
80  * Given a member function of type Ret T::f(), wraps it with a function
81  * that takes a variant_map_type and returns a variant type.
82  *
83  * Essentially, given Ret T::f(), wraps it with the following:
84  *
85  * \code
86  * variant_type g(T* t, variant_map_type input) {
87  * return variant_encode(t->f());
88  * }
89  * \endcode
90  */
91 template <typename T, typename Ret>
92 std::function<variant_type(model_base*, variant_map_type)>
93 generate_getter(Ret (T::* fn)()) {
94  return [fn](model_base* curthis, variant_map_type in)->variant_type {
95  T* t = dynamic_cast<T*>(curthis);
96  return to_variant((t->*fn)());
97  };
98 }
99 
100 
101 
102 /**
103  * Given a member function of type Ret T::f() const, wraps it with a function
104  * that takes a variant_map_type and returns a variant type.
105  *
106  * Essentially, given Ret T::f(),
107  * returns a function that performs the following:
108  * \code
109  * variant_type g(T* t, variant_map_type input) {
110  * return variant_encode(t->f());
111  * }
112  * \endcode
113  *
114  * \note Overload of generate_getter to handle
115  * the const case even though the code is... *identical*. I can't figure out
116  * how to templatize around the const.
117  */
118 template <typename T, typename Ret>
119 std::function<variant_type(model_base*, variant_map_type)>
120 generate_getter(Ret (T::* fn)() const) {
121  return [fn](model_base* curthis, variant_map_type in)->variant_type {
122  T* t = dynamic_cast<T*>(curthis);
123  return to_variant((t->*fn)());
124  };
125 }
126 
127 
128 /**
129  * Given a member function of type void T::f(S) const, wraps it with a function
130  * that takes a variant_map_type and returns a variant type.
131  *
132  * Essentially, given void T::f(S), and the input element name input_map_elem,
133  * returns a function that performs the following:
134  * \code
135  * variant_type g(T* t, variant_map_type input) {
136  * t->f(input[input_map_elem]);
137  * return variant_type();
138  * }
139  * \endcode
140  *
141  * \note Overload of generate_getter to handle
142  * the const case even though the code is... *identical*. I can't figure out
143  * how to templatize around the const.
144  */
145 template <typename T, typename SetValType>
146 std::function<variant_type(model_base*, variant_map_type)>
147 generate_setter(void (T::* fn)(SetValType), std::string input_map_elem) {
148  return [fn, input_map_elem](model_base* curthis, variant_map_type in)->variant_type {
149  SetValType val = variant_get_value<SetValType>(in[input_map_elem]);
150  T* t = dynamic_cast<T*>(curthis);
151  (t->* fn)(val);
152  return variant_type();
153  };
154 }
155 
156 
157 }
158 }
159 
160 #endif
boost::make_recursive_variant< flexible_type, std::shared_ptr< unity_sgraph_base >, dataframe_t, std::shared_ptr< model_base >, std::shared_ptr< unity_sframe_base >, std::shared_ptr< unity_sarray_base >, std::map< std::string, boost::recursive_variant_ >, std::vector< boost::recursive_variant_ >, boost::recursive_wrapper< function_closure_info > >::type variant_type
Definition: variant.hpp:24
variant_type to_variant(const T &f)
Definition: variant.hpp:308