OSSIA
Open Scenario System for Interactive Application
dataspace_base.hpp
1 #pragma once
2 #include <ossia/detail/math.hpp>
3 #include <ossia/detail/string_view.hpp>
4 #include <ossia/network/value/vec.hpp>
5 
6 #include <ratio>
7 #include <type_traits>
8 namespace ossia
9 {
10 // These algorithms are a more statically typed version
11 // of the ones found in the Jamoma dataspace library.
12 // Credits : Tim Place, Nils Peters, Trond Lossius, and certainly others.
13 // This library also tries to avoid dynamic allocation whenever possible.
14 
15 template <typename T, typename U>
16 using enable_if_same_dataspace = std::enable_if_t<
17  std::is_same<typename T::dataspace_type, typename U::dataspace_type>::value>;
18 
19 template <typename T, typename U>
20 using enable_if_different_dataspace = std::enable_if_t<
21  !std::is_same<typename T::dataspace_type, typename U::dataspace_type>::value>;
22 
23 template <typename Unit>
24 struct strong_value : Unit
25 {
26  using unit_type = Unit;
27  using value_type = typename Unit::value_type;
28  using dataspace_type = typename Unit::dataspace_type;
29  using neutral_unit = typename Unit::neutral_unit;
30  value_type dataspace_value;
31 
32  OSSIA_INLINE constexpr strong_value() noexcept
33  : dataspace_value{}
34  {
35  }
36  OSSIA_INLINE constexpr strong_value(const strong_value& other) noexcept
37  : Unit{other}
38  , dataspace_value{other.dataspace_value}
39  {
40  }
41  OSSIA_INLINE constexpr strong_value(strong_value&& other) noexcept
42  : Unit{other}
43  , dataspace_value{other.dataspace_value}
44  {
45  }
46  OSSIA_INLINE strong_value& operator=(const strong_value& other) noexcept
47  {
48  ((Unit&)*this) = other;
49  dataspace_value = other.dataspace_value;
50  return *this;
51  }
52  OSSIA_INLINE strong_value& operator=(strong_value&& other) noexcept
53  {
54  ((Unit&)*this) = other;
55  dataspace_value = other.dataspace_value;
56  return *this;
57  }
58 
59  OSSIA_INLINE constexpr strong_value(float other) noexcept
60  : dataspace_value{other}
61  {
62  }
63  OSSIA_INLINE constexpr strong_value(double other) noexcept
64  : dataspace_value{(float)other}
65  {
66  }
67  OSSIA_INLINE constexpr strong_value(int other) noexcept
68  : dataspace_value{(float)other}
69  {
70  }
71  OSSIA_INLINE constexpr strong_value(char other) noexcept
72  : dataspace_value{(float)other}
73  {
74  }
75  OSSIA_INLINE constexpr strong_value(bool other) noexcept
76  : dataspace_value{(float)other}
77  {
78  }
79  OSSIA_INLINE constexpr strong_value(std::array<float, 2> other) noexcept
80  : dataspace_value{other}
81  {
82  }
83  OSSIA_INLINE constexpr strong_value(std::array<float, 3> other) noexcept
84  : dataspace_value{other}
85  {
86  }
87  OSSIA_INLINE constexpr strong_value(std::array<float, 4> other) noexcept
88  : dataspace_value{other}
89  {
90  }
91  OSSIA_INLINE constexpr strong_value(std::array<double, 2> other) noexcept
92  : dataspace_value{(float)other[0], (float)other[1]}
93  {
94  }
95  OSSIA_INLINE constexpr strong_value(std::array<double, 3> other) noexcept
96  : dataspace_value{(float)other[0], (float)other[1], (float)other[2]}
97  {
98  }
99  OSSIA_INLINE constexpr strong_value(std::array<double, 4> other) noexcept
100  : dataspace_value{
101  (float)other[0], (float)other[1], (float)other[2], (float)other[3]}
102  {
103  }
104  OSSIA_INLINE constexpr strong_value(float f0, float f1) noexcept
105  : dataspace_value{f0, f1}
106  {
107  }
108  OSSIA_INLINE constexpr strong_value(float f0, float f1, float f2) noexcept
109  : dataspace_value{f0, f1, f2}
110  {
111  }
112  OSSIA_INLINE constexpr strong_value(float f0, float f1, float f2, float f3) noexcept
113  : dataspace_value{f0, f1, f2, f3}
114  {
115  }
116 
117  // Conversion constructor
118  template <typename U>
119  constexpr strong_value(strong_value<U> other) noexcept
120  : dataspace_value{this->from_neutral(other.to_neutral(other))}
121  {
122  static_assert(
123  std::is_same<dataspace_type, typename U::dataspace_type>::value,
124  "Trying to convert between different dataspaces");
125  }
126 
127  OSSIA_INLINE friend bool operator==(const strong_value& lhs, const strong_value& rhs)
128  {
129  return lhs.dataspace_value == rhs.dataspace_value;
130  }
131  OSSIA_INLINE friend bool operator!=(const strong_value& lhs, const strong_value& rhs)
132  {
133  return lhs.dataspace_value != rhs.dataspace_value;
134  }
135 };
136 
137 template <typename T, typename Ratio_T>
138 struct linear_unit : public T
139 {
140  OSSIA_INLINE static constexpr strong_value<typename T::neutral_unit>
141  to_neutral(strong_value<typename T::concrete_type> self)
142  {
143  return {self.dataspace_value * ratio()};
144  }
145 
146  OSSIA_INLINE static constexpr typename T::value_type
147  from_neutral(strong_value<typename T::neutral_unit> self)
148  {
149  return self.dataspace_value / ratio();
150  }
151 
152  OSSIA_INLINE static constexpr double ratio()
153  {
154  constexpr_return(double(Ratio_T::num) / double(Ratio_T::den));
155  }
156 };
157 
158 template <typename T>
159 struct unit_traits
160 {
161  static constexpr auto text() { constexpr_return(T::text()); }
162 };
163 
164 template <typename T>
165 struct unit_traits<strong_value<T>>
166 {
167  static constexpr auto text() { constexpr_return(unit_traits<T>::text()); }
168 };
169 }
Definition: git_info.h:7