Anklang-0.3.0.dev595+g65331842 anklang-0.3.0.dev595+g65331842
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
utils.hh
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#ifndef __ASE_UTILS_HH__
3#define __ASE_UTILS_HH__
4
5#include <ase/defs.hh>
6#include <ase/logging.hh>
7#include <experimental/type_traits>
8#include <any>
9
10namespace Ase {
11
12// == misc ==
13const char* ase_gettext (const String &untranslated);
14template<class A0, class... Ar> const char* ase_gettext (const char *format, const A0 &a0, const Ar &...restargs) ASE_PRINTF (1, 0);
15
16// == Date & Time ==
17String now_strftime (const String &format);
18
19// == MakeIcon ==
20namespace MakeIcon {
21IconString KwIcon (const String &keywords);
22IconString UcIcon (const String &unicode);
23IconString SvgIcon (const String &svgdata);
24IconString operator""_uc (const char *key, size_t);
25IconString operator""_icon (const char *key, size_t);
26} // MakeIcon
27
28// == Jump Tables ==
30template<typename MkFun, size_t ...INDICES> static auto
31make_indexed_table (const MkFun &mkjump, std::index_sequence<INDICES...>)
32{
33 constexpr size_t N = sizeof... (INDICES);
34 using Fun = decltype (mkjump (std::integral_constant<std::size_t, N - 1>()));
35 const std::array<Fun, N> jumptable = {
37 };
38 return jumptable;
39}
40
43template<std::size_t LAST, typename MkFun> static auto
44make_case_table (const MkFun &mkjump)
45{
46 return make_indexed_table (mkjump, std::make_index_sequence<LAST + 1>());
47}
48
49// == EventFd ==
52{
53 int fds[2];
54 void operator= (const EventFd&) = delete; // no assignments
55 explicit EventFd (const EventFd&) = delete; // no copying
56public:
57 explicit EventFd ();
58 int open ();
59 bool opened ();
60 void wakeup ();
61 int inputfd ();
62 bool pollin ();
63 void flush ();
64 /*Des*/ ~EventFd ();
65};
66
67// == CustomData ==
69template<typename T>
70class CustomDataKey : public VirtualBase {
71 /*Copy*/ CustomDataKey (const CustomDataKey&) = delete;
72 CustomDataKey& operator= (const CustomDataKey&) = delete;
73public:
74 explicit CustomDataKey () = default;
75 virtual T fallback () { return {}; }
76 const std::type_info& type () const noexcept { return typeid (T); }
77 bool has_value (const std::any &any) { return any.has_value() && any.type() == type(); }
78 T extract (const std::any &any) { return has_value (any) ? std::any_cast<T> (any) : fallback(); }
79};
80
87 struct CustomDataEntry : std::any { VirtualBase *key = nullptr; };
90 static_assert (sizeof (custom_data_) == sizeof (void*));
91 CustomDataEntry& custom_data_entry (VirtualBase *key);
92 std::any& custom_data_get (VirtualBase *key) const;
93 bool custom_data_del (VirtualBase *key);
94protected:
95 /*dtor*/ ~CustomDataContainer ();
96 void custom_data_destroy ();
97public:
99 template<class T> void set_custom_data (CustomDataKey<T> *key, T data)
100 { std::any a (data); custom_data_entry (key).swap (a); }
102 template<class T> T get_custom_data (CustomDataKey<T> *key) const
103 { return key->extract (custom_data_get (key)); }
105 template<class T> bool has_custom_data (CustomDataKey<T> *key) const
106 { return key->has_value (custom_data_get (key)); }
108 template<class T> bool del_custom_data (CustomDataKey<T> *key)
109 { return custom_data_del (key); }
110};
111
112// == Bit Manipulations ==
114constexpr uint16_t uint16_swap_le_be (uint16_t v);
115
117constexpr uint32_t uint32_swap_le_be (uint32_t v);
118
120constexpr uint64_t uint64_swap_le_be (uint64_t v);
121
122// == Implementation Details ==
123extern inline constexpr uint16_t
125{
126 return (v >> 8) | (v << 8);
127}
128
129extern inline constexpr uint32_t
131{
132 return __builtin_bswap32 (v);
133 return ( ((v & 0x000000ffU) << 24) |
134 ((v & 0x0000ff00U) << 8) |
135 ((v & 0x00ff0000U) >> 8) |
136 ((v & 0xff000000U) >> 24) );
137}
138
139extern inline constexpr uint64_t
141{
142 return __builtin_bswap64 (v);
143 return ( ((v & 0x00000000000000ffUL) << 56) |
144 ((v & 0x000000000000ff00UL) << 40) |
145 ((v & 0x0000000000ff0000UL) << 24) |
146 ((v & 0x00000000ff000000UL) << 8) |
147 ((v & 0x000000ff00000000UL) >> 8) |
148 ((v & 0x0000ff0000000000UL) >> 24) |
149 ((v & 0x00ff000000000000UL) >> 40) |
150 ((v & 0xff00000000000000UL) >> 56) );
151}
152
154template<class A0, class... Ar> const char*
155ase_gettext (const char *format, const A0 &a0, const Ar &...restargs)
156{
157 return ase_gettext (string_format (format, a0, restargs...));
158}
159
161namespace Aux {
162
163template<typename T>
164using callable_reserve_int = decltype (std::declval<T&>().reserve (int (0)));
165template<typename T>
166using callable_minus = decltype (std::declval<T>() - std::declval<T>());
167
169template<class Container, class Iteratable> Container
170container_copy (const Iteratable &source)
171{
172 Container c;
173 const auto b = std::begin (source), e = std::end (source);
175 std::experimental::is_detected<callable_minus, decltype (b)>::value) {
176 c.reserve (e - b);
177 }
178 std::copy (b, e, std::back_inserter (c));
179 return c;
180}
181
182// == Binary Lookups ==
183template<typename RandIter, class Cmp, typename Arg, int case_lookup_or_sibling_or_insertion>
184extern inline std::pair<RandIter,bool>
185binary_lookup_fuzzy (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
186{
187 RandIter current = end;
188 size_t n_elements = end - begin, offs = 0;
189 const bool want_lookup = case_lookup_or_sibling_or_insertion == 0;
190 // const bool want_sibling = case_lookup_or_sibling_or_insertion == 1;
191 const bool want_insertion_pos = case_lookup_or_sibling_or_insertion > 1;
192 ssize_t cmp = 0;
193 while (offs < n_elements)
194 {
195 size_t i = (offs + n_elements) >> 1;
196 current = begin + i;
197 cmp = cmp_elements (arg, *current);
198 if (cmp == 0)
199 return want_insertion_pos ? std::make_pair (current, true) : std::make_pair (current, /*ignored*/ false);
200 else if (cmp < 0)
201 n_elements = i;
202 else /* (cmp > 0) */
203 offs = i + 1;
204 }
205 /* check is last mismatch, cmp > 0 indicates greater key */
206 return (want_lookup
207 ? std::make_pair (end, /*ignored*/ false)
208 : (want_insertion_pos && cmp > 0)
209 ? std::make_pair (current + 1, false)
210 : std::make_pair (current, false));
211}
212
218template<typename RandIter, class Cmp, typename Arg>
219extern inline std::pair<RandIter,bool>
220binary_lookup_insertion_pos (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
221{
222 return binary_lookup_fuzzy<RandIter,Cmp,Arg,2> (begin, end, cmp_elements, arg);
223}
224
230template<typename RandIter, class Cmp, typename Arg>
231extern inline RandIter
232binary_lookup_sibling (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
233{
234 return binary_lookup_fuzzy<RandIter,Cmp,Arg,1> (begin, end, cmp_elements, arg).first;
235}
236
242template<typename RandIter, class Cmp, typename Arg>
243extern inline RandIter
244binary_lookup (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
245{
246 /* return end or exact match */
247 return binary_lookup_fuzzy<RandIter,Cmp,Arg,0> (begin, end, cmp_elements, arg).first;
248}
249
251template<typename Value> static inline int
252compare_lesser (const Value &v1, const Value &v2)
253{
254 return -(v1 < v2) | (v2 < v1);
255}
256
258template<typename Value> static inline int
259compare_greater (const Value &v1, const Value &v2)
260{
261 return (v1 < v2) | -(v2 < v1);
262}
263
264// == Vector Utils ==
265
267template<class C> inline size_t
268erase_first (C &container, const std::function<bool (typename C::value_type const &value)> &pred)
269{
270 for (auto iter = container.begin(); iter != container.end(); iter++)
271 if (pred (*iter))
272 {
273 container.erase (iter);
274 return 1;
275 }
276 return 0;
277}
278
280template<class C> inline size_t
281erase_all (C &container, const std::function<bool (typename C::value_type const &value)> &pred)
282{
283 size_t c = 0;
284 for (auto iter = container.begin(); iter != container.end(); )
285 if (pred (*iter))
286 {
287 iter = container.erase (iter);
288 c++;
289 }
290 else
291 iter++;
292 return c;
293}
294
296template<typename C> inline bool
297contains (const C &container, const std::function<bool (typename C::value_type const &value)> &pred)
298{
299 for (auto iter = container.begin(); iter != container.end(); iter++)
300 if (pred (*iter))
301 return true;
302 return false;
303}
304
306template<class T, class Compare> inline typename std::vector<T>::iterator
307insert_sorted (std::vector<T> &vec, const T &value, Compare compare)
308{
309 static_assert (std::is_signed<decltype (std::declval<Compare>() (std::declval<T>(), std::declval<T>()))>::value, "REQUIRE: int Compare (const&, const&);");
310 auto insmatch = binary_lookup_insertion_pos (vec.begin(), vec.end(), compare, value);
311 auto it = insmatch.first;
312 return vec.insert (it, value);
313}
314
315template<class IterableContainer> ssize_t
316index_of (const IterableContainer &c, const std::function<bool(const typename IterableContainer::value_type &e)> &match)
317{
318 ssize_t index = 0;
319 for (auto it = std::begin (c); it != std::end (c); ++index, ++it)
320 if (match (*it))
321 return index;
322 return -1;
323}
324
325} // Aux
326
327} // Ase
328
329#endif // __ASE_UTILS_HH__
T back_inserter(T... args)
T begin(T... args)
DataListContainer - typesafe storage and retrieval of arbitrary members.
Definition utils.hh:86
T get_custom_data(CustomDataKey< T > *key) const
Retrieve contents of the custom keyed data member, returns DataKey::fallback if nothing was set.
Definition utils.hh:102
bool has_custom_data(CustomDataKey< T > *key) const
Retrieve wether contents of the custom keyed data member exists.
Definition utils.hh:105
bool del_custom_data(CustomDataKey< T > *key)
Delete the current contents of the custom keyed data member, invokes DataKey::destroy.
Definition utils.hh:108
void set_custom_data(CustomDataKey< T > *key, T data)
Assign data to the custom keyed data member, deletes any previously set data.
Definition utils.hh:99
CustomDataKey objects are used to identify and manage custom data members of CustomDataContainer obje...
Definition utils.hh:70
virtual T fallback()
Return default T instance.
Definition utils.hh:75
const std::type_info & type() const noexcept
Return the typeid of T.
Definition utils.hh:76
Wakeup facility for IPC.
Definition utils.hh:52
bool opened()
Indicates whether eventfd has been opened.
Definition utils.cc:153
void flush()
Clear pending wakeups.
Definition utils.cc:187
int inputfd()
Returns the file descriptor for POLLIN.
Definition utils.cc:147
bool pollin()
Checks whether events are pending.
Definition utils.cc:159
int open()
Opens the eventfd and returns -errno.
Definition utils.cc:113
void wakeup()
Wakeup polling end.
Definition utils.cc:170
T copy(T... args)
T end(T... args)
T has_value(T... args)
T make_pair(T... args)
std::vector< T >::iterator insert_sorted(std::vector< T > &vec, const T &value, Compare compare)
Insert value into sorted vec using binary_lookup_insertion_pos() with compare.
Definition utils.hh:307
Container container_copy(const Iteratable &source)
Create a Container with copies of the elements of source.
Definition utils.hh:170
RandIter binary_lookup_sibling(RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
Perform a binary lookup to yield exact or nearest match.
Definition utils.hh:232
size_t erase_all(C &container, const std::function< bool(typename C::value_type const &value)> &pred)
Erase all elements for which pred() is true in vector or list.
Definition utils.hh:281
size_t erase_first(C &container, const std::function< bool(typename C::value_type const &value)> &pred)
Erase first element for which pred() is true in vector or list.
Definition utils.hh:268
RandIter binary_lookup(RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
Perform binary lookup and yield exact match or end.
Definition utils.hh:244
std::pair< RandIter, bool > binary_lookup_insertion_pos(RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
Perform a binary lookup to find the insertion position for a new element.
Definition utils.hh:220
bool contains(const C &container, const std::function< bool(typename C::value_type const &value)> &pred)
Returns true if container element for which pred() is true.
Definition utils.hh:297
The Anklang C++ API namespace.
Definition api.hh:9
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
constexpr uint64_t uint64_swap_le_be(uint64_t v)
Swap 64-Bit integers between __BIG_ENDIAN and __LITTLE_ENDIAN systems.
Definition utils.hh:140
constexpr uint32_t uint32_swap_le_be(uint32_t v)
Swap 32-Bit integers between __BIG_ENDIAN and __LITTLE_ENDIAN systems.
Definition utils.hh:130
constexpr uint16_t uint16_swap_le_be(uint16_t v)
Swap 16-Bit integers between __BIG_ENDIAN and __LITTLE_ENDIAN systems.
Definition utils.hh:124
std::string String
Convenience alias for std::string.
Definition cxxaux.hh:35
typedef uint16_t
Value type used to interface with various property types.
Definition value.hh:54
Common base type to allow casting between polymorphic classes.
Definition cxxaux.hh:220
typedef ssize_t
T type(T... args)
IconString SvgIcon(const String &svgdata)
Create an IconString consisting of an SVG string.
Definition utils.cc:95
IconString UcIcon(const String &unicode)
Create an IconString consisting of a single/double unicode character.
Definition utils.cc:73
IconString KwIcon(const String &keywords)
Create an IconString consisting of keywords.
Definition utils.cc:42