1/**
2 * Common code for writing containers.
3 *
4 * Copyright: Copyright Martin Nowak 2013.
5 * License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors:   Martin Nowak
7 */
8module rt.util.container.common;
9
10import core.stdc.stdlib : malloc, realloc;
11public import core.stdc.stdlib : free;
12import core.internal.traits : dtorIsNothrow;
13nothrow:
14
15void* xrealloc(void* ptr, size_t sz) nothrow @nogc
16{
17    import core.exception;
18
19    if (!sz) { .free(ptr); return null; }
20    if (auto nptr = .realloc(ptr, sz)) return nptr;
21    .free(ptr); onOutOfMemoryErrorNoGC();
22    assert(0);
23}
24
25void* xmalloc(size_t sz) nothrow @nogc
26{
27    import core.exception;
28    if (auto nptr = .malloc(sz))
29        return nptr;
30    onOutOfMemoryErrorNoGC();
31    assert(0);
32}
33
34void destroy(T)(ref T t) if (is(T == struct) && dtorIsNothrow!T)
35{
36    scope (failure) assert(0); // nothrow hack
37    object.destroy(t);
38}
39
40void destroy(T)(ref T t) if (!is(T == struct))
41{
42    t = T.init;
43}
44
45void initialize(T)(ref T t) if (is(T == struct))
46{
47    import core.stdc.string;
48    if (auto p = typeid(T).initializer().ptr)
49        memcpy(&t, p, T.sizeof);
50    else
51        memset(&t, 0, T.sizeof);
52}
53
54void initialize(T)(ref T t) if (!is(T == struct))
55{
56    t = T.init;
57}
58
59version (unittest) struct RC()
60{
61nothrow:
62    this(size_t* cnt) { ++*(_cnt = cnt); }
63    ~this() { if (_cnt) --*_cnt; }
64    this(this) { if (_cnt) ++*_cnt; }
65    size_t* _cnt;
66}
67