digitalmars.D - Forward Difference Compression
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (73/73) Mar 22 2014 I'm working on a range-based generic codec that uses
I'm working on a range-based generic codec that uses forwardDifference (and its reverse not yet implemented) in combination with msgpack to pack arrays of 64-bit timestamps for compacter storage. My solution so far looks like can be found here https://github.com/nordlow/justd/blob/master/algorithm_ex.d Exert: auto forwardDifference(R)(R r) pure nothrow if (isInputRange!R) { import std.range: front, empty, popFront; struct ForwardDifference { R _range; alias E = ElementType!R; // Input ElementType alias D = typeof(_range.front - _range.front); // Element Difference Type D _front; bool _initialized = false; this(R range) pure { this._range = range; } property: auto ref front() { if (!_initialized) { popFront(); } return _front; } auto ref moveFront() { popFront(); return _front; } void popFront() { if (empty is false) { _initialized = true; E rf = _range.front; _range.popFront(); if (_range.empty is false) { _front = _range.front - rf; } } } bool empty() { return _range.empty; } } return ForwardDifference(r); } auto packForwardDifference(R)(R r) if (isInputRange!R) { import std.range: front, empty; if (r.empty) return tuple(r.front, forwardDifference(r)); else return tuple(r.front, forwardDifference(r)); } unittest { import std.range: front; dln([1].packForwardDifference); dln([1, 22].packForwardDifference); dln([1, 22, 333].packForwardDifference); } gives the output algorithm_ex.d:753:debug: Tuple!(int, ForwardDifference)(1, [0]) algorithm_ex.d:754:debug: Tuple!(int, ForwardDifference)(1, [21]) algorithm_ex.d:755:debug: Tuple!(int, ForwardDifference)(1, [21, 311]) the corner cases - input []: throws exception on front and - input [1]: outputs [0] which is incorrect and should give output []. How can I efficiently treat these special cases without using .length property? I want this to work for InputRanges, not just arrays.
Mar 22 2014