Anklang 0.3.0-460-gc4ef46ba
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
member.cc
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#include "member.hh"
3#include "api.hh"
4#include "regex.hh"
5#include "strings.hh"
6#include "internal.hh"
7#include "testing.hh"
8
9namespace Ase::Lib {
10bool
11kvpairs_assign (StringS &kvs, const String &key_value_pair)
12{
13 const bool casesensitive = true;
14 return Ase::kvpairs_assign (kvs, key_value_pair, casesensitive);
15}
16
17} // Ase::Lib
18
19// == tests ==
20namespace {
21using namespace Ase;
22
23/* Related:
24 * "C++ Properties - a Library Solution", by Lois Goldthwaite
25 * https://accu.org/journals/overload/13/65/goldthwaite_255/#d0e143
26 * https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1615.pdf
27 */
28
29static String tlog;
30
31static uint base_registry_count = 0;
32struct BaseRegistry {
33 template<class O, class M> void
34 _register_parameter (O *o, M *m, const ParamExtraVals&)
35 {
36 // fake registry, test instead
37 using value_type = decltype (m->get());
38 const ptrdiff_t offset = ptrdiff_t (m) - ptrdiff_t (o);
39 auto accessor = [offset] (O *o, value_type *v) {
40 const ptrdiff_t maddr = ptrdiff_t (o) + offset;
41 M *m = reinterpret_cast<M*> (maddr);
42 if (v) m->set (*v);
43 return m->get();
44 };
45 std::function<value_type(O*,value_type*)> accessor_func = accessor;
46 tlog += string_format ("BaseRegistry=%d;\n", ++base_registry_count);
47 }
48};
49
50struct Widget : BaseRegistry {
51 char f_ = {}; void f_s (const char n) { f_ = n; f.notify(); } char f_g() const { tlog += string_format ("Widget.f=%d\n", f_); return f_; }
52 char g_ = 0; void g_s (const char &n) { g_ = n; g.notify(); } char g_g () const { return g_; }
53 int bit_;
54 int bit_g () { tlog += string_format ("realgetter=%d\n", bit_); return bit_; }
55 int bit_s (const int &bit) { tlog += string_format ("realsetter=%d\n", bit); return bit_ = bit; }
56 Ase::Member<&Widget::bit_g, &Widget::bit_s> bit [[no_unique_address]];
57 Ase::Member<&Widget::f_g,&Widget::f_s> f [[no_unique_address]];
58 Ase::Member<&Widget::g_g, &Widget::g_s> g [[no_unique_address]];
59 Widget (const std::string &foo = "") :
60 bit (this),
61 f (this, "f", { "blurb=_f_property", "" }),
62 g (this, "g", { "blurb=_g_property", "", })
63 {
64 f = 'f';
65 tlog += string_format ("sizeof(Widget)=%zd (%p)\n", sizeof (Widget), this);
66 tlog += string_format ("sizeof(bit_)=%zd (%p)\n", sizeof (bit_), &bit_);
67 tlog += string_format ("sizeof(bit)=%zd (%p) [[no_unique_address]]\n", sizeof (bit), &bit);
68 tlog += string_format ("sizeof(f_)=%zd (%p)\n", sizeof (f_), &f_);
69 tlog += string_format ("sizeof(f)=%zd (%p) [[no_unique_address]]\n", sizeof (f), &f);
70 tlog += string_format ("sizeof(g_)=%zd (%p)\n", sizeof (g_), &g_);
71 tlog += string_format ("sizeof(g)=%zd (%p) [[no_unique_address]]\n", sizeof (g), &g);
72 }
73 void
74 emit_notify (const std::string &p)
75 {
76 assert_return (!p.empty());
77 tlog += string_format ("NOTIFY: %s (%p)\n", p.c_str(), this);
78 }
79};
80
81TEST_INTEGRITY (member_tmpl_tests);
82static void
83member_tmpl_tests()
84{
85 tlog = "";
86 Widget w;
87 TASSERT (sizeof (Widget) <= 2 * sizeof (int));
88 TASSERT (w.f == 'f');
89 w.bit = -17171;
90 w.f = +71;
91 w.g = -128;
92 const int b = w.bit;
93 tlog += string_format ("Widget.bit: %d\n", b);
94 tlog += string_format ("Widget: { Widget = { .bit=%d, .f=%d, .g=%d };\n", w.bit_, w.f(), int (w.g));
95 // printerr ("%s\n", tlog.c_str());
96 TASSERT (w.bit.get() == -17171 && w.f == 71 && w.g == -128);
97 TASSERT (w.f.info ("blurb") == "_f_property");
98 TASSERT (w.g.info ("blurb") == "_g_property");
99 TASSERT (Re::search ("realgetter=-17171", tlog) >= 0);
100 TASSERT (Re::search ("NOTIFY: f ", tlog) >= 0);
101 TASSERT (Re::search ("NOTIFY: g ", tlog) >= 0);
102 TASSERT (Re::search ("BaseRegistry=3;", tlog) >= 0);
103}
104
105} // Anon
T c_str(T... args)
Implement C++ member field API with a 0-sized class from setter and getter, maybe combined with [[no_...
Definition member.hh:86
static ssize_t search(const String &regex, const String &input, Flags=DEFAULT)
Find regex in input and return match position >= 0 or return < 0 otherwise.
Definition regex.cc:217
T empty(T... args)
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
Definition internal.hh:29
#define TEST_INTEGRITY(FUNC)
Register func as an integrity test.
Definition internal.hh:77
typedef int
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...
uint32_t uint
Provide 'uint' as convenience type.
Definition cxxaux.hh:18
Helper to specify parameter ranges.
Definition parameter.hh:21
#define TASSERT(cond)
Unconditional test assertion, enters breakpoint if not fullfilled.
Definition testing.hh:24