Lagrange
Loading...
Searching...
No Matches
template.h
1/*
2 * Copyright 2020 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13#include <lagrange/utils/assert.h>
14#include <lagrange/utils/strings.h>
15#include <lagrange/utils/warning.h>
16
17#include <any>
18#include <functional>
19
20
21namespace lagrange {
22namespace ui {
23
24
25namespace util {
26
27template <typename F>
29
30template <typename F, typename Result, typename... Args>
31struct lambda_helper<Result (F::*)(Args...) const>
32{
33 using fn_type = std::function<Result(Args...)>;
34};
35} // namespace util
36
37namespace util {
38
40template <class T>
41struct AsFunction : public AsFunction<decltype(&T::operator())>
42{
43};
44
45template <class Class, class ReturnType, class Arg>
46struct AsFunction<ReturnType (Class::*)(Arg) const>
47{
48 using arg_type = Arg;
49};
50
51template <class ReturnType, class Arg>
52struct AsFunction<ReturnType (*)(Arg)>
53{
54 using arg_type = Arg;
55};
56
57template <class ReturnType, class Arg>
58struct AsFunction<ReturnType(Arg) const>
59{
60 using arg_type = Arg;
61};
63
64} // namespace util
65
66namespace detail {
67
68
69template <typename T>
71{
72 using type = std::conditional_t<std::is_same<T, const char*>::value, std::string, T>;
73};
74
75template <typename T>
76using convert_implicit_t = typename convert_implicit<T>::type;
77
78
79template <typename... Args>
81{
82 using type = std::tuple<std::remove_cv_t<std::remove_reference_t<convert_implicit_t<Args>>>...>;
83};
84
85template <typename... Args>
86using args_to_tuple_t = typename args_to_tuple<Args...>::type;
87
88
89template <typename T>
90std::unique_ptr<T> realize_default(
91 typename std::enable_if<std::is_default_constructible<T>::value>::type* dummy = 0)
92{
93 LA_IGNORE(dummy);
94 return std::make_unique<T>();
95}
96
97template <typename T>
98std::unique_ptr<T> realize_default(
99 typename std::enable_if<!std::is_default_constructible<T>::value>::type* dummy = 0)
100{
101 LA_IGNORE(dummy);
102
104 false,
106 "Cannot default construct type {}, provide a realization function to ResourceFactory",
107 typeid(T).name()));
108 return nullptr;
109}
110
111
112template <typename T, typename... Dummy>
113std::shared_ptr<T> realize_forward(const std::shared_ptr<T>& ptr)
114{
115 return ptr;
116}
117
118template <typename T, typename... Args>
119std::shared_ptr<T> realize_forward(
120 Args... args,
121 typename std::enable_if<std::is_constructible<T, Args...>::value>::type* dummy = 0)
122{
123 LA_IGNORE(dummy);
124 return std::make_shared<T>(std::forward<Args>(args)...);
125}
126
127template <typename... Args>
128void unused_variadic(Args&&... args)
129{
130 LA_IGNORE(sizeof...(args));
131}
132
133
134// Enabled if:
135// 1. Cannot construct type T from Args
136// 2. Cannot construct shared_ptr<T> from Args (makes sure this doesn't shadow realize_forward(const
137// std::shared_ptr<T>&ptr))
138// 3. Cannot construct unique_tr<T> from Args (makes sure this doesn't shadow
139// realize_forward(std::unique_ptr<T>&&))
140template <typename T, typename... Args>
141std::shared_ptr<T> realize_forward(
142 Args... args,
143 typename std::enable_if<
144 !std::is_constructible<T, Args...>::value &&
145 !std::is_constructible<std::shared_ptr<T>, Args...>::value &&
146 !std::is_constructible<std::unique_ptr<T>, Args...>::value>::type* dummy = 0)
147{
148 LA_IGNORE(dummy);
149 unused_variadic(std::forward<Args>(args)...);
151 false,
153 "Cannot construct type {} from given arguments {}, provide a realization function to "
154 "ResourceFactory",
155 typeid(T).name(),
156 typeid(std::tuple<Args...>).name()));
157
158 return nullptr;
159}
160
161// Simply copies the data
162template <typename T_out, typename T_in>
163T_out copy_or_move_element(
164 T_in& in,
165 typename std::enable_if<!std::is_rvalue_reference<T_out>::value>::type* dummy = 0)
166{
167 LA_IGNORE(dummy);
168 return in;
169}
170
171// Moves out the data
172template <typename T_out, typename T_in>
173std::remove_reference_t<T_out> copy_or_move_element(
174 T_in& in,
175 typename std::enable_if<std::is_rvalue_reference<T_out>::value>::type* dummy = 0)
176{
177 LA_IGNORE(dummy);
178 std::remove_reference_t<T_out> moved = std::move(in);
179 return moved;
180}
181
183template <typename ArgumentTuple, typename... Ts, size_t... Is>
184auto copy_or_move_impl(std::tuple<Ts...>& input, std::index_sequence<Is...>)
185{
186 return std::tuple<Ts...>{
187 copy_or_move_element<std::tuple_element_t<Is, ArgumentTuple>>(std::get<Is>(input))...};
188}
189
191template <typename ArgumentTuple, typename... Ts>
192std::tuple<Ts...> copy_or_move(std::tuple<Ts...>& input)
193{
194 return copy_or_move_impl<ArgumentTuple>(input, std::make_index_sequence<sizeof...(Ts)>{});
195}
196
197template <typename ParamPack, typename ParamPackOriginal, typename F>
198void apply_parameters(
199 const F& fn,
200 std::any& storage,
201 typename std::enable_if<std::is_constructible<ParamPack, const ParamPack&>::value>::type*
202 dummy = 0)
203{
204 LA_IGNORE(dummy);
205 // If original param pack require rvalue reference, move the data, otherwise copy
206 auto& storage_tuple = std::any_cast<ParamPack&>(storage);
207 auto forwarded_tuple = copy_or_move<ParamPackOriginal>(storage_tuple);
208
209 std::apply(fn, std::move(forwarded_tuple));
210}
211
212
213template <typename ParamPack, typename ParamPackOriginal, typename F>
214void apply_parameters(
215 const F& fn,
216 std::any& storage,
217 typename std::enable_if<!std::is_constructible<ParamPack, const ParamPack&>::value>::type*
218 dummy = 0)
219{
220 // Do nothing
221 LA_IGNORE(fn);
222 LA_IGNORE(storage);
223 LA_IGNORE(dummy);
224 // Execution should not reach here as non-copyable arguments can't be saved to std::any
225}
226
227
228} // namespace detail
229
230} // namespace ui
231} // namespace lagrange
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:177
std::string string_format(lagrange::format_string< Args... > format, Args &&... args)
Format args according to the format string fmt, and return the result as a string.
Definition strings.h:97
#define LA_IGNORE(x)
Ignore x to avoid an unused variable warning.
Definition warning.h:144
Lagrange UI Viewer and mini 3D engine.
Definition AcceleratedPicking.h:23
Main namespace for Lagrange.
Definition project.cpp:27
Definition template.h:81
Definition template.h:28