| /** | |
| * 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(); | |
| } |