Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

bad pretty print

By: a guest on Oct 28th, 2012  |  syntax: None  |  size: 4.44 KB  |  views: 37  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. import std.stdio;
  2. import std.range;
  3. import std.algorithm;
  4. import std.typecons;
  5. import std.traits;
  6. import std.conv;
  7.  
  8. private void print(T, A,
  9.         string indent = "  ",
  10.         string cum_indent = "",
  11.         string trailer = "\n") (A appender, ref T t) if(!isPointer!T) {
  12.     const string new_indent = cum_indent ~ indent;
  13.     static if (is(T == struct) || is(T == class)) {
  14.         static if(is(T == class)) {
  15.             if(!t) {
  16.                 appender.put(text("null", trailer));
  17.                 return;
  18.             }
  19.         }
  20.  
  21.         static if(__traits(compiles, t.pprint(indent, cum_indent, trailer))) {
  22.             appender.put(t.pprint(indent, cum_indent, trailer));
  23.             return;
  24.         } else static if(isIterable!T) {
  25.             appender.put("[\n");
  26.             int index = 0;
  27.  
  28.             foreach(ref item; t) {
  29.                 appender.put(new_indent);
  30.                 appender.put(text("[", index++, "]->"));
  31.                 print!(typeof(item), A, indent, new_indent)(appender, item);
  32.             }
  33.             appender.put(text(indent, "]", trailer));
  34.             return;
  35.         } else {
  36.             appender.put("{\n");
  37.             foreach (i, field; t.tupleof) {
  38.                 auto fieldName = T.tupleof[i].stringof;
  39.                 appender.put(text(new_indent, fieldName, " = "));
  40.                 print!(typeof(field), A, indent, new_indent)(appender, field);
  41.             }
  42.             appender.put(text(cum_indent, "}", trailer));
  43.             return;
  44.         }
  45.     } else static if(is(T == string)) {
  46.         appender.put(text('"', t,"\"", trailer));
  47.     } else static if(isArray!(T)) {
  48.         appender.put("[\n");
  49.         int index = 0;
  50.         foreach(item; t) {
  51.             appender.put(new_indent);
  52.             appender.put(text("[", index++, "]->"));
  53.             print!(typeof(item), A, indent, new_indent)(appender, item);
  54.         }
  55.         appender.put(text(indent, "]", trailer));
  56.         return;
  57.     } else static if(isAssociativeArray!(T)) {
  58.         appender.put("{\n");
  59.         foreach(k,v; t) {
  60.             appender.put(text(new_indent, '('));
  61.             print!(typeof(k), A, indent, new_indent, "")(appender, k);
  62.             appender.put(text(" => \n", new_indent~indent));
  63.             print!(typeof(v), A, indent, new_indent, "")(appender, v);
  64.             appender.put(text("),", trailer));
  65.         }
  66.         appender.put(text(indent, "}", trailer));
  67.         return;
  68.     } else {
  69.         appender.put(text(t, trailer));
  70.         return;
  71.     }
  72. }
  73.  
  74. private void print(T, A,
  75.         string indent = "  ",
  76.         string cum_indent = "",
  77.         string trailer = "\n")
  78. (A appender, ref T t) if(isPointer!T) {
  79.  
  80.     static if(isFunctionPointer!T) {
  81.         appender.put(text(typeid(T), trailer));
  82.     } else {
  83.         if(!t) {
  84.             appender.put(text("null", trailer));
  85.         } else {
  86.             print!(PointerTarget!T,A,indent,cum_indent,trailer)(appender, *t);
  87.         }
  88.     }
  89. }
  90.  
  91. string pp(T, string indent = " ")(ref T item) {
  92.     auto appender = appender!string();
  93.     print!(T, typeof(appender), indent) (appender, item);
  94.     return appender.data;
  95. }
  96.  
  97. struct TaxTable {
  98.     alias Tuple!(double, double) KeyValuePair;
  99.     alias KeyValuePair[] Table;
  100.     this(KeyValuePair)(KeyValuePair[] values...) {
  101.         foreach(kv; values) {
  102.             _table ~= kv;
  103.         }
  104.         sort(_table);
  105.     }
  106.  
  107.     bool opEquals(ref const TaxTable other) const {
  108.         return _table == other._table;
  109.     }
  110.  
  111.     double getRate(double taxableGrossIncome) const {
  112.         auto sortedRange = assumeSorted(_table[]);
  113.         auto needle = KeyValuePair(taxableGrossIncome, 0);
  114.         auto found = sortedRange.lowerBound(needle);
  115.         if(!found.empty) {
  116.             writeln(pp(found)); // fine
  117.             writeln(pp(found), taxableGrossIncome); // fine
  118.             writeln(taxableGrossIncome, pp(found)); // crash
  119.             return found[$-1][1];
  120.         }
  121.         return 0;
  122.     }
  123.     private {
  124.         Table _table;
  125.     }
  126. }
  127.  
  128. void main() {
  129.     with(TaxTable) {
  130.         auto kv1 = KeyValuePair(50000, 0.18), kv2 = KeyValuePair(100000, 0.25);
  131.         TaxTable tbl = TaxTable(kv1, kv2);
  132.         assert(tbl == TaxTable(kv2, kv1));
  133.         assert(0 == tbl.getRate(25000));
  134.         assert(0 == tbl.getRate(50000));
  135.         assert(0.18 == tbl.getRate(50001));
  136.         assert(0.18 == tbl.getRate(100000));
  137.         assert(0.25 == tbl.getRate(100000.01));
  138.     }
  139. }