Anklang-0.3.0.dev956+gd75ac925 anklang-0.3.0.dev956+gd75ac925
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#pragma once
3
4#include <ase/defs.hh>
5#include <ase/logging.hh>
6#include <experimental/type_traits>
7#include <any>
8
9namespace Ase {
10
11// == misc ==
12const char* ase_gettext (const String &untranslated);
13template<class A0, class... Ar> const char* ase_gettext (const char *format, const A0 &a0, const Ar &...restargs) ASE_PRINTF (1, 0);
14
15// == Date & Time ==
16String now_strftime (const String &format);
17
18// == MakeIcon ==
19namespace MakeIcon {
20IconString KwIcon (const String &keywords);
21IconString UcIcon (const String &unicode);
22IconString SvgIcon (const String &svgdata);
23IconString operator""_uc (const char *key, size_t);
24IconString operator""_icon (const char *key, size_t);
25} // MakeIcon
26
27// == Jump Tables ==
29template<typename MkFun, size_t ...INDICES> static auto
30make_indexed_table (const MkFun &mkjump, std::index_sequence<INDICES...>)
31{
32 constexpr size_t N = sizeof... (INDICES);
33 using Fun = decltype (mkjump (std::integral_constant<std::size_t, N - 1>()));
34 const std::array<Fun, N> jumptable = {
36 };
37 return jumptable;
38}
39
42template<std::size_t LAST, typename MkFun> static auto
43make_case_table (const MkFun &mkjump)
44{
45 return make_indexed_table (mkjump, std::make_index_sequence<LAST + 1>());
46}
47
48// == EventFd ==
51{
52 int fds[2];
53 void operator= (const EventFd&) = delete; // no assignments
54 explicit EventFd (const EventFd&) = delete; // no copying
55public:
56 explicit EventFd ();
57 int open ();
58 bool opened ();
59 void wakeup ();
60 int inputfd ();
61 bool pollin ();
62 void flush ();
63 /*Des*/ ~EventFd ();
64};
65
66// == CustomData ==
68template<typename T>
69class CustomDataKey : public VirtualBase {
70 /*Copy*/ CustomDataKey (const CustomDataKey&) = delete;
71 CustomDataKey& operator= (const CustomDataKey&) = delete;
72public:
73 explicit CustomDataKey () = default;
74 virtual T fallback () { return {}; }
75 const std::type_info& type () const noexcept { return typeid (T); }
76 bool has_value (const std::any &any) { return any.has_value() && any.type() == type(); }
77 T extract (const std::any &any) { return has_value (any) ? std::any_cast<T> (any) : fallback(); }
78};
79
86 struct CustomDataEntry : std::any { VirtualBase *key = nullptr; };
89 static_assert (sizeof (custom_data_) == sizeof (void*));
90 CustomDataEntry& custom_data_entry (VirtualBase *key);
91 std::any& custom_data_get (VirtualBase *key) const;
92 bool custom_data_del (VirtualBase *key);
93protected:
94 /*dtor*/ ~CustomDataContainer ();
95 void custom_data_destroy ();
96public:
98 template<class T> void set_custom_data (CustomDataKey<T> *key, T data)
99 { std::any a (data); custom_data_entry (key).swap (a); }
101 template<class T> T get_custom_data (CustomDataKey<T> *key) const
102 { return key->extract (custom_data_get (key)); }
104 template<class T> bool has_custom_data (CustomDataKey<T> *key) const
105 { return key->has_value (custom_data_get (key)); }
107 template<class T> bool del_custom_data (CustomDataKey<T> *key)
108 { return custom_data_del (key); }
109};
110
111// == Bit Manipulations ==
113constexpr uint16_t uint16_swap_le_be (uint16_t v);
114
116constexpr uint32_t uint32_swap_le_be (uint32_t v);
117
119constexpr uint64_t uint64_swap_le_be (uint64_t v);
120
121// == Implementation Details ==
122extern inline constexpr uint16_t
124{
125 return (v >> 8) | (v << 8);
126}
127
128extern inline constexpr uint32_t
130{
131 return __builtin_bswap32 (v);
132 return ( ((v & 0x000000ffU) << 24) |
133 ((v & 0x0000ff00U) << 8) |
134 ((v & 0x00ff0000U) >> 8) |
135 ((v & 0xff000000U) >> 24) );
136}
137
138extern inline constexpr uint64_t
140{
141 return __builtin_bswap64 (v);
142 return ( ((v & 0x00000000000000ffUL) << 56) |
143 ((v & 0x000000000000ff00UL) << 40) |
144 ((v & 0x0000000000ff0000UL) << 24) |
145 ((v & 0x00000000ff000000UL) << 8) |
146 ((v & 0x000000ff00000000UL) >> 8) |
147 ((v & 0x0000ff0000000000UL) >> 24) |
148 ((v & 0x00ff000000000000UL) >> 40) |
149 ((v & 0xff00000000000000UL) >> 56) );
150}
151
153template<class A0, class... Ar> const char*
154ase_gettext (const char *format, const A0 &a0, const Ar &...restargs)
155{
156 return ase_gettext (string_format (format, a0, restargs...));
157}
158
160namespace Aux {
161
162template<typename T>
163using callable_reserve_int = decltype (std::declval<T&>().reserve (int (0)));
164template<typename T>
165using callable_minus = decltype (std::declval<T>() - std::declval<T>());
166
168template<class Container, class Iteratable> Container
169container_copy (const Iteratable &source)
170{
171 Container c;
172 const auto b = std::begin (source), e = std::end (source);
174 std::experimental::is_detected<callable_minus, decltype (b)>::value) {
175 c.reserve (e - b);
176 }
177 std::copy (b, e, std::back_inserter (c));
178 return c;
179}
180
181// == Binary Lookups ==
182template<typename RandIter, class Cmp, typename Arg, int case_lookup_or_sibling_or_insertion>
183extern inline std::pair<RandIter,bool>
184binary_lookup_fuzzy (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
185{
186 RandIter current = end;
187 size_t n_elements = end - begin, offs = 0;
188 const bool want_lookup = case_lookup_or_sibling_or_insertion == 0;
189 // const bool want_sibling = case_lookup_or_sibling_or_insertion == 1;
190 const bool want_insertion_pos = case_lookup_or_sibling_or_insertion > 1;
191 ssize_t cmp = 0;
192 while (offs < n_elements)
193 {
194 size_t i = (offs + n_elements) >> 1;
195 current = begin + i;
196 cmp = cmp_elements (arg, *current);
197 if (cmp == 0)
198 return want_insertion_pos ? std::make_pair (current, true) : std::make_pair (current, /*ignored*/ false);
199 else if (cmp < 0)
200 n_elements = i;
201 else /* (cmp > 0) */
202 offs = i + 1;
203 }
204 /* check is last mismatch, cmp > 0 indicates greater key */
205 return (want_lookup
206 ? std::make_pair (end, /*ignored*/ false)
207 : (want_insertion_pos && cmp > 0)
208 ? std::make_pair (current + 1, false)
209 : std::make_pair (current, false));
210}
211
217template<typename RandIter, class Cmp, typename Arg>
218extern inline std::pair<RandIter,bool>
219binary_lookup_insertion_pos (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
220{
221 return binary_lookup_fuzzy<RandIter,Cmp,Arg,2> (begin, end, cmp_elements, arg);
222}
223
229template<typename RandIter, class Cmp, typename Arg>
230extern inline RandIter
231binary_lookup_sibling (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
232{
233 return binary_lookup_fuzzy<RandIter,Cmp,Arg,1> (begin, end, cmp_elements, arg).first;
234}
235
241template<typename RandIter, class Cmp, typename Arg>
242extern inline RandIter
243binary_lookup (RandIter begin, RandIter end, Cmp cmp_elements, const Arg &arg)
244{
245 /* return end or exact match */
246 return binary_lookup_fuzzy<RandIter,Cmp,Arg,0> (begin, end, cmp_elements, arg).first;
247}
248
250template<typename Value> static inline int
251compare_lesser (const Value &v1, const Value &v2)
252{
253 return -(v1 < v2) | (v2 < v1);
254}
255
257template<typename Value> static inline int
258compare_greater (const Value &v1, const Value &v2)
259{
260 return (v1 < v2) | -(v2 < v1);
261}
262
263// == Vector Utils ==
264
266template<class C> inline size_t
267erase_first (C &container, const std::function<bool (typename C::value_type const &value)> &pred)
268{
269 for (auto iter = container.begin(); iter != container.end(); iter++)
270 if (pred (*iter))
271 {
272 container.erase (iter);
273 return 1;
274 }
275 return 0;
276}
277
279template<class C> inline size_t
280erase_all (C &container, const std::function<bool (typename C::value_type const &value)> &pred)
281{
282 size_t c = 0;
283 for (auto iter = container.begin(); iter != container.end(); )
284 if (pred (*iter))
285 {
286 iter = container.erase (iter);
287 c++;
288 }
289 else
290 iter++;
291 return c;
292}
293
295template<typename C> inline bool
296contains (const C &container, const std::function<bool (typename C::value_type const &value)> &pred)
297{
298 for (auto iter = container.begin(); iter != container.end(); iter++)
299 if (pred (*iter))
300 return true;
301 return false;
302}
303
305template<class T, class Compare> inline typename std::vector<T>::iterator
306insert_sorted (std::vector<T> &vec, const T &value, Compare compare)
307{
308 static_assert (std::is_signed<decltype (std::declval<Compare>() (std::declval<T>(), std::declval<T>()))>::value, "REQUIRE: int Compare (const&, const&);");
309 auto insmatch = binary_lookup_insertion_pos (vec.begin(), vec.end(), compare, value);
310 auto it = insmatch.first;
311 return vec.insert (it, value);
312}
313
314template<class IterableContainer> ssize_t
315index_of (const IterableContainer &c, const std::function<bool(const typename IterableContainer::value_type &e)> &match)
316{
317 ssize_t index = 0;
318 for (auto it = std::begin (c); it != std::end (c); ++index, ++it)
319 if (match (*it))
320 return index;
321 return -1;
322}
323
324} // Aux
325
326} // Ase
327
T back_inserter(T... args)
T begin(T... args)
DataListContainer - typesafe storage and retrieval of arbitrary members.
Definition utils.hh:85
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:101
bool has_custom_data(CustomDataKey< T > *key) const
Retrieve wether contents of the custom keyed data member exists.
Definition utils.hh:104
bool del_custom_data(CustomDataKey< T > *key)
Delete the current contents of the custom keyed data member, invokes DataKey::destroy.
Definition utils.hh:107
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:98
CustomDataKey objects are used to identify and manage custom data members of CustomDataContainer obje...
Definition utils.hh:69
virtual T fallback()
Return default T instance.
Definition utils.hh:74
const std::type_info & type() const noexcept
Return the typeid of T.
Definition utils.hh:75
Wakeup facility for IPC.
Definition utils.hh:51
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:306
Container container_copy(const Iteratable &source)
Create a Container with copies of the elements of source.
Definition utils.hh:169
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:231
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:280
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:267
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:243
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:219
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:296
The Anklang C++ API namespace.
Definition api.hh:8
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:139
constexpr uint32_t uint32_swap_le_be(uint32_t v)
Swap 32-Bit integers between __BIG_ENDIAN and __LITTLE_ENDIAN systems.
Definition utils.hh:129
constexpr uint16_t uint16_swap_le_be(uint16_t v)
Swap 16-Bit integers between __BIG_ENDIAN and __LITTLE_ENDIAN systems.
Definition utils.hh:123
std::string String
Convenience alias for std::string.
Definition cxxaux.hh:34
typedef uint16_t
Value type used to interface with various property types.
Definition value.hh:53
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