Casts and @trusted

Anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jun 13 18:56:34 PDT 2014


This seems to work from quick testing, but it has casts in 
get_ref that I want to avoid.
cast(T*) refs[i] is obviously not @safe.
cast(T*) _buffer[read].ptr doesn't seem necessary, since 
_buffer[read] is conceivably a T so _buffer[read].ptr should be a 
T*. But without it I get "Error: cannot implicitly convert 
expression (&this._buffer[read]) of type const(char)* to char[5]*"
I do want to pass in a preallocated buffer to store some 
pointers, at least as one get option. I also want to disallow 
modification to the ring buffer through those pointers. How might 
I rework things to enable that usage while being @safe?

enum TakeStrategy { cyclic, once }
alias TS = TakeStrategy;
struct StaticRingBuffer(T, size_t cap) {
	static assert (cap > 1);
	private T[cap] _buffer;
	private size_t _index = cap-1;
	private size_t _fill = 0;
	@property size_t extra() nothrow const {
		return cap-fill;
	}
	@property size_t index() nothrow const {
		return _index;
	}
	@property size_t fill() nothrow const {
		return _fill;
	}

	@property const ref front() nothrow const {
		return _buffer[index];
	}

	void put(T ele) pure nothrow {
		if (index == cap-1) _index = 0;
		else ++_index;
		_buffer[index] = ele;
		
		if (fill < cap) ++_fill;
	}

	void put(T[] eles) pure nothrow {
		foreach(e; eles) put(e);
	}

	@trusted void get_ref(TS strat=TS.cyclic)(size_t n, const(T*)[] 
refs) const nothrow
	{
		assert(refs.length == n);
		static if (strat==TS.once) size_t numreads = fixNToFill(n);
		else size_t numreads = n;

		size_t read = index;
		foreach(i;0..numreads) {
			cast(T*) refs[i] = cast(T*) _buffer[read].ptr;
			if (read == 0) read = fill-1;
			else --read;
		}

	}

	private size_t fixNToFill(size_t n) const nothrow {
		return (n > fill) ? fill : n;
	}
}


More information about the Digitalmars-d-learn mailing list