| /** |
| * Contains a bitfield used by the GC. |
| * |
| * Copyright: Copyright Digital Mars 2005 - 2013. |
| * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). |
| * Authors: Walter Bright, David Friedman, Sean Kelly |
| */ |
| |
| /* Copyright Digital Mars 2005 - 2013. |
| * Distributed under the Boost Software License, Version 1.0. |
| * (See accompanying file LICENSE or copy at |
| * http://www.boost.org/LICENSE_1_0.txt) |
| */ |
| module gc.bits; |
| |
| |
| import core.bitop; |
| import core.stdc.string; |
| import core.stdc.stdlib; |
| import core.exception : onOutOfMemoryError; |
| |
| struct GCBits |
| { |
| alias size_t wordtype; |
| |
| enum BITS_PER_WORD = (wordtype.sizeof * 8); |
| enum BITS_SHIFT = (wordtype.sizeof == 8 ? 6 : 5); |
| enum BITS_MASK = (BITS_PER_WORD - 1); |
| enum BITS_1 = cast(wordtype)1; |
| |
| wordtype* data; |
| size_t nbits; |
| |
| void Dtor() nothrow |
| { |
| if (data) |
| { |
| free(data); |
| data = null; |
| } |
| } |
| |
| void alloc(size_t nbits) nothrow |
| { |
| this.nbits = nbits; |
| data = cast(typeof(data[0])*)calloc(nwords, data[0].sizeof); |
| if (!data) |
| onOutOfMemoryError(); |
| } |
| |
| wordtype test(size_t i) const nothrow |
| in |
| { |
| assert(i < nbits); |
| } |
| body |
| { |
| return core.bitop.bt(data, i); |
| } |
| |
| int set(size_t i) nothrow |
| in |
| { |
| assert(i < nbits); |
| } |
| body |
| { |
| return core.bitop.bts(data, i); |
| } |
| |
| int clear(size_t i) nothrow |
| in |
| { |
| assert(i <= nbits); |
| } |
| body |
| { |
| return core.bitop.btr(data, i); |
| } |
| |
| void zero() nothrow |
| { |
| memset(data, 0, nwords * wordtype.sizeof); |
| } |
| |
| void copy(GCBits *f) nothrow |
| in |
| { |
| assert(nwords == f.nwords); |
| } |
| body |
| { |
| memcpy(data, f.data, nwords * wordtype.sizeof); |
| } |
| |
| @property size_t nwords() const pure nothrow |
| { |
| return (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT; |
| } |
| } |
| |
| unittest |
| { |
| GCBits b; |
| |
| b.alloc(786); |
| assert(!b.test(123)); |
| assert(!b.clear(123)); |
| assert(!b.set(123)); |
| assert(b.test(123)); |
| assert(b.clear(123)); |
| assert(!b.test(123)); |
| |
| b.set(785); |
| b.set(0); |
| assert(b.test(785)); |
| assert(b.test(0)); |
| b.zero(); |
| assert(!b.test(785)); |
| assert(!b.test(0)); |
| |
| GCBits b2; |
| b2.alloc(786); |
| b2.set(38); |
| b.copy(&b2); |
| assert(b.test(38)); |
| b2.Dtor(); |
| b.Dtor(); |
| } |