2#include <ossia/detail/config.hpp>
4#include <ossia/detail/fmt.hpp>
5#include <ossia/detail/parse_relax.hpp>
6#include <ossia/network/value/value.hpp>
10#include <boost/type_traits/function_traits.hpp>
18template <
typename T, std::
size_t N>
19struct array_size<std::array<T, N>> :
public std::integral_constant<std::size_t, N>
23template <
typename Target,
typename =
void>
29struct value_converter<
ossia::impulse>
33 ossia::impulse operator()(
const U&)
38 ossia::impulse operator()() {
return {}; }
42struct numeric_value_converter
46 T operator()(impulse)
const {
return T{}; }
47 T operator()(int32_t v) {
return v; }
48 T operator()(
float v) {
return v; }
49 T operator()(
bool v) {
return v; }
50 T operator()(
char v) {
return v; }
51 T operator()()
const {
return T{}; }
53 T operator()(
const std::string& v)
const =
delete;
54 T operator()(
const vec2f& v)
const {
return v[0]; }
55 T operator()(
const vec3f& v)
const {
return v[0]; }
56 T operator()(
const vec4f& v)
const {
return v[0]; }
58 T operator()(
const std::vector<ossia::value>& v)
const
60 return !v.empty() ? convert<T>(v[0]) : T{};
62 T operator()(
const value_map_type& v)
const
64 return !v.empty() ? convert<T>(v.begin()->second) : T{};
69struct value_converter<int32_t> :
public numeric_value_converter<int32_t>
71 using numeric_value_converter<int32_t>::operator();
72 int32_t operator()(
const std::string& v)
const
74 if(
auto n = parse_relax<int>(v))
80struct value_converter<float> :
public numeric_value_converter<float>
82 using numeric_value_converter<
float>::operator();
83 float operator()(
const std::string& v)
const
85 if(
auto n = parse_relax<float>(v))
91struct value_converter<double> :
public numeric_value_converter<double>
93 using numeric_value_converter<
double>::operator();
94 double operator()(
const std::string& v)
const
96 if(
auto n = parse_relax<double>(v))
102struct value_converter<bool> :
public numeric_value_converter<bool>
104 using numeric_value_converter<
bool>::operator();
105 bool operator()(
const std::string& v)
const
107 return v.starts_with(
'T') || v.starts_with(
't') || v.starts_with(
'Y')
108 || v.starts_with(
'y') || v ==
"1";
112struct value_converter<char> :
public numeric_value_converter<char>
116#if defined(OSSIA_HAS_FMT)
119 fmt::memory_buffer& wr;
121 void operator()(impulse)
const { fmt::format_to(fmt::appender(wr),
"impulse"); }
122 void operator()(int32_t v)
const { fmt::format_to(fmt::appender(wr),
"{}", v); }
123 void operator()(
float v)
const { fmt::format_to(fmt::appender(wr),
"{}", v); }
124 void operator()(
bool v)
const
127 fmt::format_to(fmt::appender(wr),
"true");
129 fmt::format_to(fmt::appender(wr),
"false");
131 void operator()(
char v)
const { fmt::format_to(fmt::appender(wr),
"{}", v); }
132 void operator()(
const std::string& v)
const
134 fmt::format_to(fmt::appender(wr),
"{}", v);
136 void operator()()
const { }
137 template <std::
size_t N>
138 void operator()(std::array<float, N> v)
const
140 fmt::format_to(fmt::appender(wr),
"[{}", v[0]);
141 for(std::size_t i = 1; i < N; i++)
142 fmt::format_to(fmt::appender(wr),
", {}", v[i]);
143 fmt::format_to(fmt::appender(wr),
"]");
145 void operator()(
const std::vector<ossia::value>& v)
const
147 using namespace std::literals;
148 fmt::format_to(fmt::appender(wr),
"[");
149 const auto n = v.size();
154 for(std::size_t i = 1; i < n; i++)
156 fmt::format_to(fmt::appender(wr),
", ");
160 fmt::format_to(fmt::appender(wr),
"]");
162 void operator()(
const value_map_type& v)
const
164 using namespace std::literals;
165 fmt::format_to(fmt::appender(wr),
"{{");
166 const auto n = v.size();
170 fmt::format_to(fmt::appender(wr),
"\"{}\": ", it->first);
171 it->second.apply(*
this);
173 for(++it; it != v.end(); ++it)
175 fmt::format_to(fmt::appender(wr),
", \"{}\": ", it->first);
176 it->second.apply(*
this);
179 fmt::format_to(fmt::appender(wr),
"}}");
184struct value_converter<std::string>
186 const std::string& cur;
187 using T = std::string;
188 T operator()(impulse)
const {
return "impulse"; }
189 T operator()(int32_t v)
const {
return fmt::format(
"{}", v); }
190 T operator()(
float v)
const {
return fmt::format(
"{}", v); }
191 T operator()(
bool v)
const
193 using namespace std::literals;
194 return v ?
"true"s :
"false"s;
196 T operator()(
char v)
const {
return std::string(1, v); }
197 T operator()(
const std::string& v)
const {
return v; }
199 T operator()()
const {
return {}; }
201 template <std::
size_t N>
202 T operator()(std::array<float, N> v)
const
206 fmt::format_to(std::back_inserter(wr),
"[{}", v[0]);
207 for(std::size_t i = 1; i < N; i++)
208 fmt::format_to(std::back_inserter(wr),
", {}", v[i]);
209 fmt::format_to(std::back_inserter(wr),
"]");
213 T operator()(
const std::vector<ossia::value>& v)
const
215 using namespace std::literals;
216 fmt::memory_buffer wr;
218 return {wr.data(), wr.size()};
221 T operator()(
const value_map_type& v)
const
223 using namespace std::literals;
224 fmt::memory_buffer wr;
226 return {wr.data(), wr.size()};
232struct value_converter<std::string>
234 const std::string& cur;
235 using T = std::string;
236 T operator()(impulse)
const {
return "impulse"; }
237 T operator()(int32_t v)
const {
return std::to_string(v); }
238 T operator()(
float v)
const {
return std::to_string(v); }
239 T operator()(
bool v)
const
241 using namespace std::literals;
242 return v ?
"true"s :
"false"s;
244 T operator()(
char v)
const {
return std::string(1, v); }
245 T operator()(
const std::string& v)
const {
return v; }
247 T operator()()
const {
return {}; }
249 template <std::
size_t N>
250 T operator()(std::array<float, N> v)
const
255 wr += std::to_string(v[0]);
257 for(std::size_t i = 1; i < N; i++)
260 wr += std::to_string(v[i]);
266 T operator()(
const std::vector<ossia::value>& v)
const {
return "(TODO)"; }
268 T operator()(
const value_map_type& v)
const {
return "(TODO)"; }
273struct value_converter<std::vector<ossia::value>>
275 const std::vector<ossia::value>& cur;
276 template <
typename U>
277 std::vector<ossia::value> operator()(
const U& u)
282 template <std::
size_t N>
283 std::vector<ossia::value> operator()(
const std::array<float, N>& u)
285 std::vector<ossia::value> v;
286 for(std::size_t i = 0; i < N; i++)
288 v.emplace_back(
float{u[i]});
293 std::vector<ossia::value> operator()(
const std::vector<ossia::value>& t) {
return t; }
294 std::vector<ossia::value> operator()(std::vector<ossia::value>&& t)
299 std::vector<ossia::value> operator()() {
return {}; }
303struct value_converter<value_map_type>
305 const value_map_type& cur;
306 template <
typename U>
307 value_map_type operator()(
const U& u)
309 return value_map_type{{
"0", u}};
312 template <std::
size_t N>
313 value_map_type operator()(
const std::array<float, N>& u)
316 for(std::size_t i = 0; i < N; i++)
318 v[std::to_string(i)] =
float{u[i]};
323 value_map_type operator()(
const std::vector<ossia::value>& t)
326 for(std::size_t i = 0; i < t.size(); i++)
328 v[std::to_string(i)] = t[i];
332 value_map_type operator()(std::vector<ossia::value>&& t)
335 for(std::size_t i = 0; i < t.size(); i++)
337 v[std::to_string(i)] = std::move(t[i]);
342 value_map_type operator()(
const value_map_type& t) {
return t; }
343 value_map_type operator()(value_map_type&& t) {
return std::move(t); }
345 value_map_type operator()() {
return {}; }
348template <std::
size_t N>
349struct value_converter<std::array<float, N>>
351 const std::array<float, N>& cur;
352 template <
typename U>
353 std::array<float, N> operator()(
const U&)
358 std::array<float, N> operator()(std::array<float, N> v) {
return v; }
360 template <std::
size_t M>
361 std::array<float, N> operator()(std::array<float, M> v)
363 std::array<float, N> a = cur;
364 for(std::size_t i = 0; i < std::min(N, M); i++)
371 std::array<float, N> operator()(
float f)
373 std::array<float, N> a;
378 std::array<float, N> operator()(int32_t f)
380 std::array<float, N> a;
385 std::array<float, N> operator()(
char f)
387 std::array<float, N> a;
392 std::array<float, N> operator()(
bool f)
394 std::array<float, N> a;
399 std::array<float, N> operator()(
const std::vector<ossia::value>& t)
401 return convert<std::array<float, N>>(t);
404 std::array<float, N> operator()(
const value_map_type& t) {
return {}; }
406 std::array<float, N> operator()() {
return {}; }
413 return val.apply(detail::value_converter<T>{{T{}}});
419 val = val.apply(detail::value_converter<T>{{T{}}});
425 return val.apply(detail::value_converter<T>{{cur}});
430T convert(
const std::vector<ossia::value>& val)
437 const auto N = std::min(val.size(), detail::array_size<T>::value);
438 for(std::size_t i = 0; i < N; i++)
440 res[i] = val[i].apply(detail::value_converter<typename T::value_type>{});
446template <
typename Fun,
typename... Args>
452 return f(ossia::value_trait<impulse>{}, std::forward<Args>(args)...);
454 return f(ossia::value_trait<bool>{}, std::forward<Args>(args)...);
456 return f(ossia::value_trait<int32_t>{}, std::forward<Args>(args)...);
457 case val_type::FLOAT:
458 return f(ossia::value_trait<float>{}, std::forward<Args>(args)...);
460 return f(ossia::value_trait<value_map_type>{}, std::forward<Args>(args)...);
462 return f(ossia::value_trait<std::string>{}, std::forward<Args>(args)...);
465 ossia::value_trait<std::vector<ossia::value>>{}, std::forward<Args>(args)...);
467 return f(ossia::value_trait<vec2f>{}, std::forward<Args>(args)...);
469 return f(ossia::value_trait<vec3f>{}, std::forward<Args>(args)...);
471 return f(ossia::value_trait<vec4f>{}, std::forward<Args>(args)...);
476 ossia_do_throw(invalid_value_type_error,
"lift: Invalid type");
477 return decltype(f(ossia::value_trait<impulse>{}, std::forward<Args>(args)...)){};
479template <
typename Fun,
typename... Args>
485 f(ossia::value_trait<impulse>{}, std::forward<Args>(args)...);
488 f(ossia::value_trait<bool>{}, std::forward<Args>(args)...);
491 f(ossia::value_trait<int32_t>{}, std::forward<Args>(args)...);
493 case val_type::FLOAT:
494 f(ossia::value_trait<float>{}, std::forward<Args>(args)...);
497 f(ossia::value_trait<value_map_type>{}, std::forward<Args>(args)...);
500 f(ossia::value_trait<std::string>{}, std::forward<Args>(args)...);
503 f(ossia::value_trait<std::vector<ossia::value>>{}, std::forward<Args>(args)...);
506 f(ossia::value_trait<vec2f>{}, std::forward<Args>(args)...);
509 f(ossia::value_trait<vec3f>{}, std::forward<Args>(args)...);
512 f(ossia::value_trait<vec4f>{}, std::forward<Args>(args)...);
520extern template double ossia::convert<double>(
const ossia::value&);
521extern template float ossia::convert<float>(
const ossia::value&);
522extern template int32_t ossia::convert<int32_t>(
const ossia::value&);
524extern template bool ossia::convert<bool>(
const ossia::value&);
525extern template std::string ossia::convert<std::string>(
const ossia::value&);
526extern template std::vector<ossia::value>
527ossia::convert<std::vector<ossia::value>>(
const ossia::value&);
528extern template ossia::vec2f ossia::convert<ossia::vec2f>(
const ossia::value&);
529extern template ossia::vec3f ossia::convert<ossia::vec3f>(
const ossia::value&);
530extern template ossia::vec4f ossia::convert<ossia::vec4f>(
const ossia::value&);
The value class.
Definition value.hpp:173
val_type
Enum to represent the types that a value can take.
Definition parameter_properties.hpp:16