Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import std.stdio;
- import std.range;
- import std.algorithm;
- import std.typecons;
- import std.traits;
- import std.conv;
- private void print(T, A,
- string indent = " ",
- string cum_indent = "",
- string trailer = "\n") (A appender, ref T t) if(!isPointer!T) {
- const string new_indent = cum_indent ~ indent;
- static if (is(T == struct) || is(T == class)) {
- static if(is(T == class)) {
- if(!t) {
- appender.put(text("null", trailer));
- return;
- }
- }
- static if(__traits(compiles, t.pprint(indent, cum_indent, trailer))) {
- appender.put(t.pprint(indent, cum_indent, trailer));
- return;
- } else static if(isIterable!T) {
- appender.put("[\n");
- int index = 0;
- foreach(ref item; t) {
- appender.put(new_indent);
- appender.put(text("[", index++, "]->"));
- print!(typeof(item), A, indent, new_indent)(appender, item);
- }
- appender.put(text(indent, "]", trailer));
- return;
- } else {
- appender.put("{\n");
- foreach (i, field; t.tupleof) {
- auto fieldName = T.tupleof[i].stringof;
- appender.put(text(new_indent, fieldName, " = "));
- print!(typeof(field), A, indent, new_indent)(appender, field);
- }
- appender.put(text(cum_indent, "}", trailer));
- return;
- }
- } else static if(is(T == string)) {
- appender.put(text('"', t,"\"", trailer));
- } else static if(isArray!(T)) {
- appender.put("[\n");
- int index = 0;
- foreach(item; t) {
- appender.put(new_indent);
- appender.put(text("[", index++, "]->"));
- print!(typeof(item), A, indent, new_indent)(appender, item);
- }
- appender.put(text(indent, "]", trailer));
- return;
- } else static if(isAssociativeArray!(T)) {
- appender.put("{\n");
- foreach(k,v; t) {
- appender.put(text(new_indent, '('));
- print!(typeof(k), A, indent, new_indent, "")(appender, k);
- appender.put(text(" => \n", new_indent~indent));
- print!(typeof(v), A, indent, new_indent, "")(appender, v);
- appender.put(text("),", trailer));
- }
- appender.put(text(indent, "}", trailer));
- return;
- } else {
- appender.put(text(t, trailer));
- return;
- }
- }
- private void print(T, A,
- string indent = " ",
- string cum_indent = "",
- string trailer = "\n")
- (A appender, ref T t) if(isPointer!T) {
- static if(isFunctionPointer!T) {
- appender.put(text(typeid(T), trailer));
- } else {
- if(!t) {
- appender.put(text("null", trailer));
- } else {
- print!(PointerTarget!T,A,indent,cum_indent,trailer)(appender, *t);
- }
- }
- }
- string pp(T, string indent = " ")(ref T item) {
- auto appender = appender!string();
- print!(T, typeof(appender), indent) (appender, item);
- return appender.data;
- }
- struct TaxTable {
- alias Tuple!(double, double) KeyValuePair;
- alias KeyValuePair[] Table;
- this(KeyValuePair)(KeyValuePair[] values...) {
- foreach(kv; values) {
- _table ~= kv;
- }
- sort(_table);
- }
- bool opEquals(ref const TaxTable other) const {
- return _table == other._table;
- }
- double getRate(double taxableGrossIncome) const {
- auto sortedRange = assumeSorted(_table[]);
- auto needle = KeyValuePair(taxableGrossIncome, 0);
- auto found = sortedRange.lowerBound(needle);
- if(!found.empty) {
- writeln(pp(found)); // fine
- writeln(pp(found), taxableGrossIncome); // fine
- writeln(taxableGrossIncome, pp(found)); // crash
- return found[$-1][1];
- }
- return 0;
- }
- private {
- Table _table;
- }
- }
- void main() {
- with(TaxTable) {
- auto kv1 = KeyValuePair(50000, 0.18), kv2 = KeyValuePair(100000, 0.25);
- TaxTable tbl = TaxTable(kv1, kv2);
- assert(tbl == TaxTable(kv2, kv1));
- assert(0 == tbl.getRate(25000));
- assert(0 == tbl.getRate(50000));
- assert(0.18 == tbl.getRate(50001));
- assert(0.18 == tbl.getRate(100000));
- assert(0.25 == tbl.getRate(100000.01));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement