OSSIA
Open Scenario System for Interactive Application
apply_domain.hpp
1 #pragma once
2 #include <ossia/network/domain/detail/array_domain.hpp>
3 #include <ossia/network/domain/detail/generic_domain.hpp>
4 #include <ossia/network/domain/detail/numeric_domain.hpp>
5 #include <ossia/network/domain/detail/value_set_domain.hpp>
7 #define FAST_COMPILES // See also clamp_visitors.hpp
8 
9 #if defined(FAST_COMPILES)
10 namespace ossia
11 {
12 template <typename T>
13 auto& move(const T& t)
14 {
15  return t;
16 }
17 }
18 #else
19 namespace ossia
20 {
21 template <typename T>
22 constexpr typename std::remove_reference<T>::type&& move(T&& t) noexcept
23 {
24  return static_cast<typename std::remove_reference<T>::type&&>(t);
25 }
26 }
27 #endif
28 
29 namespace ossia
30 {
31 
32 struct apply_domain_visitor
33 {
34  bounding_mode b;
35 
36  // General case with incompatible values
37  template <typename T, typename U>
38  OSSIA_INLINE ossia::value operator()(const T& value, const U& bad_domain) const
39  {
40  return {};
41  }
42 
43  // Generic case
44  template <typename T>
45  OSSIA_INLINE ossia::value
46  operator()(T&& value, const domain_base<ossia::value>& domain) const
47  {
48  return generic_clamp{domain}(b, std::move(value));
49  }
50 
51  template <typename T>
52  OSSIA_INLINE ossia::value
53  operator()(const T& value, const domain_base<ossia::value>& domain) const
54  {
55  return generic_clamp{domain}(b, value);
56  }
57 
58  // Values without meaningful domains
59  OSSIA_INLINE ossia::value
60  operator()(impulse value, const domain_base<impulse>& domain) const
61  {
62  return value;
63  }
64  // Numeric values
65  ossia::value operator()(int32_t value, const domain_base<int32_t>& domain) const;
66  ossia::value operator()(int32_t value, const domain_base<float>& domain) const;
67  ossia::value operator()(float value, const domain_base<int32_t>& domain) const;
68  ossia::value operator()(float value, const domain_base<float>& domain) const;
69  ossia::value operator()(bool value, const domain_base<bool>& domain) const;
70 
71  // Strings
72  OSSIA_INLINE ossia::value
73  operator()(const std::string& value, const domain_base<std::string>& domain) const
74  {
75  return value_set_clamp<domain_base<std::string>>{domain}(b, value);
76  }
77  OSSIA_INLINE ossia::value
78  operator()(std::string&& value, const domain_base<std::string>& domain) const
79  {
80  return value_set_clamp<domain_base<std::string>>{domain}(b, std::move(value));
81  }
82 
83  // Lists
84  // First case : list with another domain : we try to filter all the values
85  // of the list that are filterable by this domain.
86  // They are defined outside the class to handle a GCC bug...
87  template <typename T>
89  operator()(const std::vector<ossia::value>& value, const domain_base<T>& domain) const;
90  template <typename T>
92  operator()(std::vector<ossia::value>&& value, const domain_base<T>& domain) const;
93 
94  ossia::value operator()(
95  const std::vector<ossia::value>& value,
96  const domain_base<ossia::value>& domain) const;
97  ossia::value operator()(
98  std::vector<ossia::value>&& value, const domain_base<ossia::value>& domain) const;
99 
100  // Second case : we filter a whole list.
102  operator()(const std::vector<ossia::value>& value, const vector_domain& domain) const;
104  operator()(std::vector<ossia::value>&& value, const vector_domain& domain) const;
105 
106  // Vec : we can either filter each value, or filter the whole shebang
108  operator()(const std::array<float, 2>& value, const domain_base<float>& domain) const;
109  ossia::value operator()(
110  const std::array<float, 2>& value, const domain_base<int32_t>& domain) const;
112  operator()(const std::array<float, 2>& value, const domain_base<bool>& domain) const;
114  operator()(const std::array<float, 2>& value, const vecf_domain<2>& domain) const;
116  operator()(const std::array<float, 2>& value, const vector_domain& domain) const;
117 
119  operator()(const std::array<float, 3>& value, const domain_base<float>& domain) const;
120  ossia::value operator()(
121  const std::array<float, 3>& value, const domain_base<int32_t>& domain) const;
123  operator()(const std::array<float, 3>& value, const domain_base<bool>& domain) const;
125  operator()(const std::array<float, 3>& value, const vecf_domain<3>& domain) const;
127  operator()(const std::array<float, 3>& value, const vector_domain& domain) const;
128 
130  operator()(const std::array<float, 4>& value, const domain_base<float>& domain) const;
131  ossia::value operator()(
132  const std::array<float, 4>& value, const domain_base<int32_t>& domain) const;
134  operator()(const std::array<float, 4>& value, const domain_base<bool>& domain) const;
136  operator()(const std::array<float, 4>& value, const vecf_domain<4>& domain) const;
138  operator()(const std::array<float, 4>& value, const vector_domain& domain) const;
139 };
140 
141 template <typename Domain_T>
142 struct list_apply_domain_helper
143 {
144  const apply_domain_visitor& vis;
145  const Domain_T& dom;
146 
147  template <typename U>
148  OSSIA_INLINE ossia::value operator()(U&& u) const
149  {
150  return vis(std::forward<U>(u), dom);
151  }
152 };
153 
154 template <typename T>
155 ossia::value apply_domain_visitor::operator()(
156  const std::vector<ossia::value>& value, const domain_base<T>& domain) const
157 {
158  std::vector<ossia::value> res = value;
159  for(auto& val : res)
160  {
161  if(val.get_type() == ossia::value_trait<T>::ossia_enum)
162  val = ossia::apply_nonnull(
163  list_apply_domain_helper<domain_base<T>>{*this, domain}, val.v);
164  }
165  return ossia::value{std::move(res)};
166 }
167 
168 template <typename T>
169 ossia::value apply_domain_visitor::operator()(
170  std::vector<ossia::value>&& value, const domain_base<T>& domain) const
171 {
172  for(auto& val : value)
173  {
174  if(val.get_type() == ossia::value_trait<T>::ossia_enum)
175  val = ossia::apply_nonnull(
176  list_apply_domain_helper<domain_base<T>>{*this, domain}, std::move(val.v));
177  }
178  // TODO currently other values (strings, etc...) are ignored; what should we
179  // do here ?
180  return ossia::value{std::move(value)};
181 }
182 }
The value class.
Definition: value.hpp:173
Definition: git_info.h:7
bounding_mode
Address behaviors at crossing domain boundaries.
Definition: parameter_properties.hpp:56