1 //Written in the D programming language
2 /*
3  * Formatted output for output ranges.
4  *
5  * Distributed under the Boost Software License, Version 1.0.
6  * (See http://www.boost.org/LICENSE_1_0.txt)
7  *
8  * Authors: Jason den Dulk
9  *
10  * Written in the D language.
11  */
12 
13 /*
14  * I use print instead of write to avoid conflicts with std.stdio, but
15  * otherwise they should function the same.
16  *
17  * Most of the implementation is ripped off from Phobos.
18  */
19 
20 module jaypha.io.print;
21 
22 import std.traits;
23 import std.conv;
24 import std.range.primitives;
25 
26 void print(Writer,S...)(Writer w, S args)
27 {
28   foreach (arg; args)
29   {
30     alias typeof(arg) A;
31     static if (is(A == enum))
32     {
33       std.format.formattedWrite(w, "%s", arg);
34     }
35     else static if (isSomeString!A && isOutputRange!(Writer,A))
36     {
37       w.put(arg);
38     }
39     else static if (isBoolean!A)
40     {
41       w.put(arg ? "true" : "false");
42     }
43     else static if (isSomeChar!A && isOutputRange!(Writer,A))
44     {
45       w.put(arg);
46     }
47     else static if (__traits(compiles,to!string(arg)))
48     {
49       w.put(to!string(arg));
50     }
51     else static if (__traits(compiles,arg.copy(w)))
52     {
53       arg.copy(w);
54     }
55     else static if (__traits(compiles,arg.toString()))
56     {
57       stream.put(arg.toString());
58     }
59     else
60     {
61       // Most general case
62       std.format.formattedWrite(w, "%s", arg);
63     }
64   }
65 }
66 
67 void println(Writer,S...)(Writer w, S args)
68 {
69   w.print(args);
70   w.put('\n');
71 }
72 
73 void fprint(Writer,Char, A...)(Writer w, in Char[] fmt, A args)
74 {
75   std.format.formattedWrite(w, fmt, args);
76 }
77 
78 void fprintln(Writer,Char, A...)(Writer w, in Char[] fmt, A args)
79 {
80   std.format.formattedWrite(w, fmt, args);
81   w.put('\n');
82 }
83 
84 
85 unittest
86 {
87   import std.array;
88 
89   auto napp = appender!string();
90 
91   auto d = "for".dup;
92 
93   napp.print("ab",5, true,'g');
94   auto ss = napp.data;
95   assert(napp.data == "ab5trueg");
96   napp.print("xyz\n");
97   assert(napp.data == "ab5truegxyz\n");
98   napp.fprint("b%smat",d);
99   assert(napp.data == "ab5truegxyz\nbformat");
100   napp.fprintln("a %d format",10);
101   assert(napp.data == "ab5truegxyz\nbformata 10 format\n");
102   napp.println();
103   assert(napp.data == "ab5truegxyz\nbformata 10 format\n\n");
104 }