THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

280 lines
12 KiB

<?php
$inputs = Array();
$outputs = Array();
$bodies = Array();
/*********************************/
/* Input functor */
$inputs['Inf'] = Array(
'templateparams' => Array('InputFunctor'),
'enables' => Array('DeflIsInputFunctor'),
'params' => Array('InputFunctor&& inputfun'),
'abortable' => ('DeflInputAbortable_Type(std::decay_t<std::result_of_t<InputFunctor()>>)'),
'before' => 'gunzip_ns::dummy btfun{};'
);
/* Input iterator */
$inputs['InI'] = Array(
'templateparams' => Array('InputIterator'),
'enables' => Array('DeflIsInputIterator'),
'params' => Array('InputIterator&& input'),
'abortable' => ('DeflInputAbortable_Type(std::decay_t<decltype(*input)>)'),
'before' => 'auto inputfun = [&]() { auto r = *input; ++input; return r; };'."\n".
'gunzip_ns::dummy btfun{};'
);
/* Input iterator begin and end */
$inputs['InI2'] = Array(
'templateparams' => Array('InputIterator'),
'enables' => Array('DeflIsInputIterator'),
'params' => Array('InputIterator&& begin', 'InputIterator&& end'),
'abortable' => ('1'),
'before' => 'auto inputfun = [&]() { if(begin==end) { return -1; } int r = *begin; ++begin; return r; };'."\n".
'gunzip_ns::dummy btfun{};'
);
/* Input iterator and number of bytes */
$inputs['InIl'] = Array(
'templateparams' => Array('InputIterator', 'SizeType'),
'enables' => Array('DeflIsInputIterator', 'DeflIsSizeType'),
'params' => Array('InputIterator&& begin', 'SizeType&& length'),
'abortable' => ('1'),
'before' => 'typename std::iterator_traits<std::decay_t<InputIterator>>::difference_type remain(length);'."\n".
'auto inputfun = [&]() -> std::common_type_t<int, decltype(*begin)> '."\n".
'{ if(!remain) { return -1; } --remain; int r = *begin; ++begin; return r; };'."\n".
'gunzip_ns::dummy btfun{};'
);
/* Bidir iterator and number of bytes */
$inputs['InBl'] = Array(
'templateparams' => Array('BidirIterator', 'SizeType'),
'enables' => Array('DeflIsBidirIterator', 'DeflIsSizeType'),
'params' => Array('BidirIterator&& begin', 'SizeType&& length'),
'abortable' => ('1'),
'before' => 'typename std::iterator_traits<std::decay_t<BidirIterator>>::difference_type remain(length), savestate{};'."\n".
'auto inputfun = [&]() -> std::common_type_t<int, decltype(*begin)> '."\n".
'{ if(!remain) { return -1; } --remain; int r = *begin; ++begin; return r; };'."\n".
'auto btfun = [&](bool act) { if(act) { begin -= (savestate-remain); remain = savestate; } else savestate = remain; };'
);
/* Forward/bidir/const random iterator */
$inputs['InF'] = Array(
'templateparams' => Array('ForwardIterator'),
'enables' => Array('DeflIsForwardIterator'),
'params' => Array('ForwardIterator&& begin'),
'abortable' => ('0'),
'before' => 'ForwardIterator saved;'.
'auto inputfun = [&]() { auto r = *begin; ++begin; return r; };'."\n".
'auto btfun = [&](bool act) { if(act) begin = saved; else saved = std::move(begin); };'
);
/* Forward/bidir/const random iterator begin and end */
$inputs['InF2'] = Array(
'templateparams' => Array('ForwardIterator'),
'enables' => Array('DeflIsForwardIterator'),
'params' => Array('ForwardIterator&& begin', 'ForwardIterator&& end'),
'abortable' => ('1'),
'before' => 'ForwardIterator saved;'."\n".
'auto inputfun = [&]() { if(begin==end) { return -1; } int r = *begin; ++begin; return r; };'."\n".
'auto btfun = [&](bool act) { if(act) begin = saved; else saved = std::move(begin); };'
);
/*********************************/
/* Output functor and window functor */
$outputs['Outfw'] = Array(
'templateparams' => Array('OutputFunctor', 'WindowFunctor'),
'enables' => Array('DeflIsOutputFunctor', 'DeflIsWindowFunctor'),
'params' => Array('OutputFunctor&& output', 'WindowFunctor&& outputcopy'),
'abortable' => '(DeflOutputAbortable_OutputFunctor & DeflOutputAbortable_WindowFunctor)',
'before' => ''
);
/* Output functor */
$outputs['Outf'] = Array(
'templateparams' => Array('OutputFunctor'),
'enables' => Array('DeflIsOutputFunctor'),
'params' => Array('OutputFunctor&& output_orig'),
'abortable' => 'DeflOutputAbortable_OutputFunctor',
'before' =>
'DeflDeclWindow'."\n".
'auto output = [&](unsigned char l)'."\n".
'{'."\n".
' window.Data[window.Head++ % gunzip_ns::MAX_WINDOW_SIZE] = l;'."\n".
' return output_orig(l);'."\n".
'};'."\n".
'auto outputcopy = [&](std::uint_least16_t length, std::uint_fast32_t offs)'."\n".
'{'."\n".
' /* length=0 means that offs is the size of the window. */'."\n".
' for(; length>0; --length)'."\n".
' {'."\n".
' unsigned char byte = window.Data[(window.Head - offs) % gunzip_ns::MAX_WINDOW_SIZE];'."\n".
' if(gunzip_ns::OutputHelper<bool(Abortable&2)>::output(output, byte))'."\n".
' break;'."\n".
' }'."\n".
' return length;'."\n".
'};'
);
/* Output iterator */
$outputs['OutI'] = Array(
'templateparams' => Array('OutputIterator'),
'enables' => Array('DeflIsOutputIterator'),
'params' => Array('OutputIterator&& target'),
'abortable' => '0',
'before' =>
'DeflDeclWindow'."\n".
'auto output = [&](unsigned char l)'."\n".
'{'."\n".
' window.Data[window.Head++ % gunzip_ns::MAX_WINDOW_SIZE] = l;'."\n".
' *target = l; ++target;'."\n".
'};'."\n".
'auto outputcopy = [&](std::uint_least16_t length, std::uint_fast32_t offs)'."\n".
'{'."\n".
' /* length=0 means that offs is the size of the window. */'."\n".
' for(; length>0; --length)'."\n".
' {'."\n".
' unsigned char byte = window.Data[(window.Head - offs) % gunzip_ns::MAX_WINDOW_SIZE];'."\n".
' output(byte);'."\n".
' }'."\n".
' return false;'."\n".
'};'
);
/* Random access iterator */
$outputs['Outr'] = Array(
'templateparams' => Array('RandomAccessIterator'),
'enables' => Array('DeflIsRandomAccessIterator'),
'params' => Array('RandomAccessIterator&& target'),
'abortable' => '0',
'before' =>
'auto output = [&](unsigned char l) { *target = l; ++target; };'."\n".
'auto outputcopy = [&](std::uint_least16_t length, std::uint_fast32_t offs)'."\n".
'{'."\n".
' /* length=0 means that offs is the size of the window. */'."\n".
' for(; length--; ++target) { *target = *(target-offs); }'."\n".
'};'
);
/* Random access iterator and length limit */
$outputs['Outrl'] = Array(
'templateparams' => Array('RandomAccessIterator', 'SizeType2'),
'enables' => Array('DeflIsRandomAccessIterator', 'DeflIsSizeType2'),
'params' => Array('RandomAccessIterator&& target', 'SizeType2&& target_limit'),
'abortable' => '2',
'before' =>
'typename std::iterator_traits<std::decay_t<RandomAccessIterator>>::difference_type used{}, cap=target_limit;'."\n".
'auto output = [&](unsigned char l)'."\n".
'{'."\n".
' if(used >= cap) return true;'."\n".
' target[used] = l; ++used;'."\n".
' return false;'."\n".
'};'."\n".
'auto outputcopy = [&](std::uint_least16_t length, std::uint_fast32_t offs)'."\n".
'{'."\n".
' /* length=0 means that offs is the size of the window. */'."\n".
' for(; length > 0 && used < cap; ++used, --length)'."\n".
' {'."\n".
' target[used] = target[used - offs];'."\n".
' }'."\n".
' return length;'."\n".
'};'
);
/* Random access iterator begin and end */
$outputs['Outr2'] = Array(
'templateparams' => Array('RandomAccessIterator'),
'enables' => Array('DeflIsRandomAccessIterator'),
'params' => Array('RandomAccessIterator&& target_begin', 'RandomAccessIterator&& target_end'),
'abortable' => '2',
'before' =>
'auto output = [&](unsigned char l)'."\n".
'{'."\n".
' if(target_begin == target_end) return true;'."\n".
' *target_begin = l; ++target_begin;'."\n".
' return false;'."\n".
'};'."\n".
'auto outputcopy = [&](std::uint_least16_t length, std::uint_fast32_t offs)'."\n".
'{'."\n".
' /* length=0 means that offs is the size of the window. */'."\n".
' for(; length > 0 && !(target_begin == target_end); --length, ++target_begin)'."\n".
' {'."\n".
' *target_begin = *(target_begin - offs);'."\n".
' }'."\n".
' return length;'."\n".
'};'
);
/*********************************/
$bodies = Array();
$bodies['Tk0'] = Array(
'params' => Array('DeflateTrackNoSize = {}'),
'ret' => 'int',
'body' => 'return gunzip_ns::Gunzip<Abortable>(inputfun, output, outputcopy, btfun);'
);
$bodies['Tki'] = Array(
'params' => Array('DeflateTrackInSize'),
'ret' => 'std::pair<int, std::uint_fast64_t>',
'body' => 'gunzip_ns::SizeTracker<DeflateTrackInSize> tracker;'."\n".
'return tracker(gunzip_ns::Gunzip<Abortable>(tracker.template ForwardInput(inputfun), output, outputcopy, btfun));'
);
$bodies['Tko'] = Array(
'params' => Array('DeflateTrackOutSize'),
'ret' => 'std::pair<int, std::uint_fast64_t>',
'body' => 'gunzip_ns::SizeTracker<DeflateTrackOutSize> tracker;'."\n".
'return tracker(gunzip_ns::Gunzip<Abortable>(inputfun, tracker.template ForwardOutput(output), tracker.template ForwardWindow(outputcopy), btfun));'
);
$bodies['Tkb'] = Array(
'params' => Array('DeflateTrackBothSize'),
'ret' => 'std::pair<int, std::pair<std::uint_fast64_t,std::uint_fast64_t>>',
'body' => 'gunzip_ns::SizeTracker<DeflateTrackBothSize> tracker;'."\n".
'return tracker(gunzip_ns::Gunzip<Abortable>(tracker.template ForwardInput(inputfun), tracker.template ForwardOutput(output), tracker.template ForwardWindow(outputcopy), btfun));'
);
$replacements = Array();
function Replace(&$string, $hint)
{
global $replacements;
if($string == '') return;
if(!isset($replacements[$string]))
{
$v = "DEFL_MACRO_$hint";
$replacements[$string] = $v;
$s = "\n$string";
$s = str_replace("\n", " \\\n ", $s);
print "#define $v $s\n";
}
$string = $replacements[$string];
}
foreach($inputs as $k=>&$input) Replace($input['before'], $k);
foreach($outputs as $k=>&$output) Replace($output['before'], $k);
foreach($bodies as $k=>&$body) Replace($body['body'], $k);
unset($input); unset($output); unset($body);
foreach($inputs as $input)
foreach($outputs as $output)
foreach($bodies as $body)
{
$s = 'template<';
foreach($input['templateparams'] as $p) { print "{$s}typename {$p}"; $s=','; }
foreach($output['templateparams'] as $p) { print "{$s}typename {$p}"; $s=','; }
$s = ">\nstd::enable_if_t<";
foreach($input['enables'] as $p) { print "{$s}{$p}"; $s=' && '; }
foreach($output['enables'] as $p) { print "{$s}{$p}"; $s=' && '; }
$s = ", {$body['ret']}>\n Deflate(";
foreach($input['params'] as $p) { print "{$s}{$p}"; $s=','; }
foreach($output['params'] as $p) { print "{$s}{$p}"; $s=','; }
foreach($body['params'] as $p) { print "{$s}{$p}"; $s=','; }
print ")\n{\nconstexpr unsigned char Abortable = {$input['abortable']} | {$output['abortable']};\n{$input['before']} {$output['before']} {$body['body']}\n}\n\n";
}
foreach($replacements as $s=>$v) print "#undef $v\n";