]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/mod.rs
rollup merge of #17355 : gamazeps/issue17210
[rust.git] / src / libcore / fmt / mod.rs
1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Utilities for formatting and printing strings
12
13 #![allow(unused_variable)]
14
15 use any;
16 use cell::{Cell, Ref, RefMut};
17 use collections::Collection;
18 use iter::{Iterator, range};
19 use kinds::Copy;
20 use mem;
21 use option::{Option, Some, None};
22 use ops::Deref;
23 use result::{Ok, Err};
24 use result;
25 use slice::{Slice, ImmutableSlice};
26 use slice;
27 use str::StrSlice;
28 use str;
29
30 pub use self::num::radix;
31 pub use self::num::Radix;
32 pub use self::num::RadixFmt;
33
34 mod num;
35 mod float;
36 pub mod rt;
37
38 pub type Result = result::Result<(), FormatError>;
39
40 /// The error type which is returned from formatting a message into a stream.
41 ///
42 /// This type does not support transmission of an error other than that an error
43 /// occurred. Any extra information must be arranged to be transmitted through
44 /// some other means.
45 pub enum FormatError {
46     /// A generic write error occurred during formatting, no other information
47     /// is transmitted via this variant.
48     WriteError,
49 }
50
51 /// A collection of methods that are required to format a message into a stream.
52 ///
53 /// This trait is the type which this modules requires when formatting
54 /// information. This is similar to the standard library's `io::Writer` trait,
55 /// but it is only intended for use in libcore.
56 ///
57 /// This trait should generally not be implemented by consumers of the standard
58 /// library. The `write!` macro accepts an instance of `io::Writer`, and the
59 /// `io::Writer` trait is favored over implementing this trait.
60 pub trait FormatWriter {
61     /// Writes a slice of bytes into this writer, returning whether the write
62     /// succeeded.
63     ///
64     /// This method can only succeed if the entire byte slice was successfully
65     /// written, and this method will not return until all data has been
66     /// written or an error occurs.
67     ///
68     /// # Errors
69     ///
70     /// This function will return an instance of `FormatError` on error.
71     fn write(&mut self, bytes: &[u8]) -> Result;
72
73     /// Glue for usage of the `write!` macro with implementers of this trait.
74     ///
75     /// This method should generally not be invoked manually, but rather through
76     /// the `write!` macro itself.
77     fn write_fmt(&mut self, args: &Arguments) -> Result { write(self, args) }
78 }
79
80 /// A struct to represent both where to emit formatting strings to and how they
81 /// should be formatted. A mutable version of this is passed to all formatting
82 /// traits.
83 pub struct Formatter<'a> {
84     /// Flags for formatting (packed version of rt::Flag)
85     pub flags: uint,
86     /// Character used as 'fill' whenever there is alignment
87     pub fill: char,
88     /// Boolean indication of whether the output should be left-aligned
89     pub align: rt::Alignment,
90     /// Optionally specified integer width that the output should be
91     pub width: Option<uint>,
92     /// Optionally specified precision for numeric types
93     pub precision: Option<uint>,
94
95     buf: &'a mut FormatWriter+'a,
96     curarg: slice::Items<'a, Argument<'a>>,
97     args: &'a [Argument<'a>],
98 }
99
100 enum Void {}
101
102 /// This struct represents the generic "argument" which is taken by the Xprintf
103 /// family of functions. It contains a function to format the given value. At
104 /// compile time it is ensured that the function and the value have the correct
105 /// types, and then this struct is used to canonicalize arguments to one type.
106 pub struct Argument<'a> {
107     formatter: extern "Rust" fn(&Void, &mut Formatter) -> Result,
108     value: &'a Void,
109 }
110
111 impl<'a> Arguments<'a> {
112     /// When using the format_args!() macro, this function is used to generate the
113     /// Arguments structure. The compiler inserts an `unsafe` block to call this,
114     /// which is valid because the compiler performs all necessary validation to
115     /// ensure that the resulting call to format/write would be safe.
116     #[doc(hidden)] #[inline]
117     pub unsafe fn new<'a>(pieces: &'static [&'static str],
118                           args: &'a [Argument<'a>]) -> Arguments<'a> {
119         Arguments {
120             pieces: mem::transmute(pieces),
121             fmt: None,
122             args: args
123         }
124     }
125
126     /// This function is used to specify nonstandard formatting parameters.
127     /// The `pieces` array must be at least as long as `fmt` to construct
128     /// a valid Arguments structure.
129     #[doc(hidden)] #[inline]
130     pub unsafe fn with_placeholders<'a>(pieces: &'static [&'static str],
131                                         fmt: &'static [rt::Argument<'static>],
132                                         args: &'a [Argument<'a>]) -> Arguments<'a> {
133         Arguments {
134             pieces: mem::transmute(pieces),
135             fmt: Some(mem::transmute(fmt)),
136             args: args
137         }
138     }
139 }
140
141 /// This structure represents a safely precompiled version of a format string
142 /// and its arguments. This cannot be generated at runtime because it cannot
143 /// safely be done so, so no constructors are given and the fields are private
144 /// to prevent modification.
145 ///
146 /// The `format_args!` macro will safely create an instance of this structure
147 /// and pass it to a function or closure, passed as the first argument. The
148 /// macro validates the format string at compile-time so usage of the `write`
149 /// and `format` functions can be safely performed.
150 pub struct Arguments<'a> {
151     // Format string pieces to print.
152     pieces: &'a [&'a str],
153
154     // Placeholder specs, or `None` if all specs are default (as in "{}{}").
155     fmt: Option<&'a [rt::Argument<'a>]>,
156
157     // Dynamic arguments for interpolation, to be interleaved with string
158     // pieces. (Every argument is preceded by a string piece.)
159     args: &'a [Argument<'a>],
160 }
161
162 impl<'a> Show for Arguments<'a> {
163     fn fmt(&self, fmt: &mut Formatter) -> Result {
164         write(fmt.buf, self)
165     }
166 }
167
168 /// When a format is not otherwise specified, types are formatted by ascribing
169 /// to this trait. There is not an explicit way of selecting this trait to be
170 /// used for formatting, it is only if no other format is specified.
171 pub trait Show {
172     /// Formats the value using the given formatter.
173     fn fmt(&self, &mut Formatter) -> Result;
174 }
175
176 /// Format trait for the `b` character
177 pub trait Bool {
178     /// Formats the value using the given formatter.
179     fn fmt(&self, &mut Formatter) -> Result;
180 }
181
182 /// Format trait for the `c` character
183 pub trait Char {
184     /// Formats the value using the given formatter.
185     fn fmt(&self, &mut Formatter) -> Result;
186 }
187
188 /// Format trait for the `i` and `d` characters
189 pub trait Signed {
190     /// Formats the value using the given formatter.
191     fn fmt(&self, &mut Formatter) -> Result;
192 }
193
194 /// Format trait for the `u` character
195 pub trait Unsigned {
196     /// Formats the value using the given formatter.
197     fn fmt(&self, &mut Formatter) -> Result;
198 }
199
200 /// Format trait for the `o` character
201 pub trait Octal {
202     /// Formats the value using the given formatter.
203     fn fmt(&self, &mut Formatter) -> Result;
204 }
205
206 /// Format trait for the `t` character
207 pub trait Binary {
208     /// Formats the value using the given formatter.
209     fn fmt(&self, &mut Formatter) -> Result;
210 }
211
212 /// Format trait for the `x` character
213 pub trait LowerHex {
214     /// Formats the value using the given formatter.
215     fn fmt(&self, &mut Formatter) -> Result;
216 }
217
218 /// Format trait for the `X` character
219 pub trait UpperHex {
220     /// Formats the value using the given formatter.
221     fn fmt(&self, &mut Formatter) -> Result;
222 }
223
224 /// Format trait for the `s` character
225 pub trait String {
226     /// Formats the value using the given formatter.
227     fn fmt(&self, &mut Formatter) -> Result;
228 }
229
230 /// Format trait for the `p` character
231 pub trait Pointer {
232     /// Formats the value using the given formatter.
233     fn fmt(&self, &mut Formatter) -> Result;
234 }
235
236 /// Format trait for the `f` character
237 pub trait Float {
238     /// Formats the value using the given formatter.
239     fn fmt(&self, &mut Formatter) -> Result;
240 }
241
242 /// Format trait for the `e` character
243 pub trait LowerExp {
244     /// Formats the value using the given formatter.
245     fn fmt(&self, &mut Formatter) -> Result;
246 }
247
248 /// Format trait for the `E` character
249 pub trait UpperExp {
250     /// Formats the value using the given formatter.
251     fn fmt(&self, &mut Formatter) -> Result;
252 }
253
254 // FIXME #11938 - UFCS would make us able call the above methods
255 // directly Show::show(x, fmt).
256 macro_rules! uniform_fn_call_workaround {
257     ($( $name: ident, $trait_: ident; )*) => {
258         $(
259             #[doc(hidden)]
260             pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
261                 x.fmt(fmt)
262             }
263             )*
264     }
265 }
266 uniform_fn_call_workaround! {
267     secret_show, Show;
268     secret_bool, Bool;
269     secret_char, Char;
270     secret_signed, Signed;
271     secret_unsigned, Unsigned;
272     secret_octal, Octal;
273     secret_binary, Binary;
274     secret_lower_hex, LowerHex;
275     secret_upper_hex, UpperHex;
276     secret_string, String;
277     secret_pointer, Pointer;
278     secret_float, Float;
279     secret_lower_exp, LowerExp;
280     secret_upper_exp, UpperExp;
281 }
282
283 static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument {
284     position: rt::ArgumentNext,
285     format: rt::FormatSpec {
286         fill: ' ',
287         align: rt::AlignUnknown,
288         flags: 0,
289         precision: rt::CountImplied,
290         width: rt::CountImplied,
291     }
292 };
293
294 /// The `write` function takes an output stream, a precompiled format string,
295 /// and a list of arguments. The arguments will be formatted according to the
296 /// specified format string into the output stream provided.
297 ///
298 /// # Arguments
299 ///
300 ///   * output - the buffer to write output to
301 ///   * args - the precompiled arguments generated by `format_args!`
302 pub fn write(output: &mut FormatWriter, args: &Arguments) -> Result {
303     let mut formatter = Formatter {
304         flags: 0,
305         width: None,
306         precision: None,
307         buf: output,
308         align: rt::AlignUnknown,
309         fill: ' ',
310         args: args.args,
311         curarg: args.args.iter(),
312     };
313
314     let mut pieces = args.pieces.iter();
315
316     match args.fmt {
317         None => {
318             // We can use default formatting parameters for all arguments.
319             for _ in range(0, args.args.len()) {
320                 try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
321                 try!(formatter.run(&DEFAULT_ARGUMENT));
322             }
323         }
324         Some(fmt) => {
325             // Every spec has a corresponding argument that is preceded by
326             // a string piece.
327             for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
328                 try!(formatter.buf.write(piece.as_bytes()));
329                 try!(formatter.run(arg));
330             }
331         }
332     }
333
334     // There can be only one trailing string piece left.
335     match pieces.next() {
336         Some(piece) => {
337             try!(formatter.buf.write(piece.as_bytes()));
338         }
339         None => {}
340     }
341
342     Ok(())
343 }
344
345 impl<'a> Formatter<'a> {
346
347     // First up is the collection of functions used to execute a format string
348     // at runtime. This consumes all of the compile-time statics generated by
349     // the format! syntax extension.
350     fn run(&mut self, arg: &rt::Argument) -> Result {
351         // Fill in the format parameters into the formatter
352         self.fill = arg.format.fill;
353         self.align = arg.format.align;
354         self.flags = arg.format.flags;
355         self.width = self.getcount(&arg.format.width);
356         self.precision = self.getcount(&arg.format.precision);
357
358         // Extract the correct argument
359         let value = match arg.position {
360             rt::ArgumentNext => { *self.curarg.next().unwrap() }
361             rt::ArgumentIs(i) => self.args[i],
362         };
363
364         // Then actually do some printing
365         (value.formatter)(value.value, self)
366     }
367
368     fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> {
369         match *cnt {
370             rt::CountIs(n) => { Some(n) }
371             rt::CountImplied => { None }
372             rt::CountIsParam(i) => {
373                 let v = self.args[i].value;
374                 unsafe { Some(*(v as *const _ as *const uint)) }
375             }
376             rt::CountIsNextParam => {
377                 let v = self.curarg.next().unwrap().value;
378                 unsafe { Some(*(v as *const _ as *const uint)) }
379             }
380         }
381     }
382
383     // Helper methods used for padding and processing formatting arguments that
384     // all formatting traits can use.
385
386     /// Performs the correct padding for an integer which has already been
387     /// emitted into a byte-array. The byte-array should *not* contain the sign
388     /// for the integer, that will be added by this method.
389     ///
390     /// # Arguments
391     ///
392     /// * is_positive - whether the original integer was positive or not.
393     /// * prefix - if the '#' character (FlagAlternate) is provided, this
394     ///   is the prefix to put in front of the number.
395     /// * buf - the byte array that the number has been formatted into
396     ///
397     /// This function will correctly account for the flags provided as well as
398     /// the minimum width. It will not take precision into account.
399     pub fn pad_integral(&mut self,
400                         is_positive: bool,
401                         prefix: &str,
402                         buf: &[u8])
403                         -> Result {
404         use char::Char;
405         use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
406
407         let mut width = buf.len();
408
409         let mut sign = None;
410         if !is_positive {
411             sign = Some('-'); width += 1;
412         } else if self.flags & (1 << (FlagSignPlus as uint)) != 0 {
413             sign = Some('+'); width += 1;
414         }
415
416         let mut prefixed = false;
417         if self.flags & (1 << (FlagAlternate as uint)) != 0 {
418             prefixed = true; width += prefix.char_len();
419         }
420
421         // Writes the sign if it exists, and then the prefix if it was requested
422         let write_prefix = |f: &mut Formatter| {
423             for c in sign.into_iter() {
424                 let mut b = [0, ..4];
425                 let n = c.encode_utf8(b).unwrap_or(0);
426                 try!(f.buf.write(b.slice_to(n)));
427             }
428             if prefixed { f.buf.write(prefix.as_bytes()) }
429             else { Ok(()) }
430         };
431
432         // The `width` field is more of a `min-width` parameter at this point.
433         match self.width {
434             // If there's no minimum length requirements then we can just
435             // write the bytes.
436             None => {
437                 try!(write_prefix(self)); self.buf.write(buf)
438             }
439             // Check if we're over the minimum width, if so then we can also
440             // just write the bytes.
441             Some(min) if width >= min => {
442                 try!(write_prefix(self)); self.buf.write(buf)
443             }
444             // The sign and prefix goes before the padding if the fill character
445             // is zero
446             Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => {
447                 self.fill = '0';
448                 try!(write_prefix(self));
449                 self.with_padding(min - width, rt::AlignRight, |f| f.buf.write(buf))
450             }
451             // Otherwise, the sign and prefix goes after the padding
452             Some(min) => {
453                 self.with_padding(min - width, rt::AlignRight, |f| {
454                     try!(write_prefix(f)); f.buf.write(buf)
455                 })
456             }
457         }
458     }
459
460     /// This function takes a string slice and emits it to the internal buffer
461     /// after applying the relevant formatting flags specified. The flags
462     /// recognized for generic strings are:
463     ///
464     /// * width - the minimum width of what to emit
465     /// * fill/align - what to emit and where to emit it if the string
466     ///                provided needs to be padded
467     /// * precision - the maximum length to emit, the string is truncated if it
468     ///               is longer than this length
469     ///
470     /// Notably this function ignored the `flag` parameters
471     pub fn pad(&mut self, s: &str) -> Result {
472         // Make sure there's a fast path up front
473         if self.width.is_none() && self.precision.is_none() {
474             return self.buf.write(s.as_bytes());
475         }
476         // The `precision` field can be interpreted as a `max-width` for the
477         // string being formatted
478         match self.precision {
479             Some(max) => {
480                 // If there's a maximum width and our string is longer than
481                 // that, then we must always have truncation. This is the only
482                 // case where the maximum length will matter.
483                 let char_len = s.char_len();
484                 if char_len >= max {
485                     let nchars = ::cmp::min(max, char_len);
486                     return self.buf.write(s.slice_chars(0, nchars).as_bytes());
487                 }
488             }
489             None => {}
490         }
491         // The `width` field is more of a `min-width` parameter at this point.
492         match self.width {
493             // If we're under the maximum length, and there's no minimum length
494             // requirements, then we can just emit the string
495             None => self.buf.write(s.as_bytes()),
496             // If we're under the maximum width, check if we're over the minimum
497             // width, if so it's as easy as just emitting the string.
498             Some(width) if s.char_len() >= width => {
499                 self.buf.write(s.as_bytes())
500             }
501             // If we're under both the maximum and the minimum width, then fill
502             // up the minimum width with the specified string + some alignment.
503             Some(width) => {
504                 self.with_padding(width - s.char_len(), rt::AlignLeft, |me| {
505                     me.buf.write(s.as_bytes())
506                 })
507             }
508         }
509     }
510
511     /// Runs a callback, emitting the correct padding either before or
512     /// afterwards depending on whether right or left alignment is requested.
513     fn with_padding(&mut self,
514                     padding: uint,
515                     default: rt::Alignment,
516                     f: |&mut Formatter| -> Result) -> Result {
517         use char::Char;
518         let align = match self.align {
519             rt::AlignUnknown => default,
520             _ => self.align
521         };
522
523         let (pre_pad, post_pad) = match align {
524             rt::AlignLeft => (0u, padding),
525             rt::AlignRight | rt::AlignUnknown => (padding, 0u),
526             rt::AlignCenter => (padding / 2, (padding + 1) / 2),
527         };
528
529         let mut fill = [0u8, ..4];
530         let len = self.fill.encode_utf8(fill).unwrap_or(0);
531
532         for _ in range(0, pre_pad) {
533             try!(self.buf.write(fill.slice_to(len)));
534         }
535
536         try!(f(self));
537
538         for _ in range(0, post_pad) {
539             try!(self.buf.write(fill.slice_to(len)));
540         }
541
542         Ok(())
543     }
544
545     /// Writes some data to the underlying buffer contained within this
546     /// formatter.
547     pub fn write(&mut self, data: &[u8]) -> Result {
548         self.buf.write(data)
549     }
550
551     /// Writes some formatted information into this instance
552     pub fn write_fmt(&mut self, fmt: &Arguments) -> Result {
553         write(self.buf, fmt)
554     }
555 }
556
557 /// This is a function which calls are emitted to by the compiler itself to
558 /// create the Argument structures that are passed into the `format` function.
559 #[doc(hidden)] #[inline]
560 pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
561                        t: &'a T) -> Argument<'a> {
562     unsafe {
563         Argument {
564             formatter: mem::transmute(f),
565             value: mem::transmute(t)
566         }
567     }
568 }
569
570 /// When the compiler determines that the type of an argument *must* be a string
571 /// (such as for select), then it invokes this method.
572 #[doc(hidden)] #[inline]
573 pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
574     argument(secret_string, s)
575 }
576
577 /// When the compiler determines that the type of an argument *must* be a uint
578 /// (such as for plural), then it invokes this method.
579 #[doc(hidden)] #[inline]
580 pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
581     argument(secret_unsigned, s)
582 }
583
584 // Implementations of the core formatting traits
585
586 impl<'a, T: Show> Show for &'a T {
587     fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
588 }
589 impl<'a, T: Show> Show for &'a mut T {
590     fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
591 }
592 impl<'a> Show for &'a Show+'a {
593     fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
594 }
595
596 impl Bool for bool {
597     fn fmt(&self, f: &mut Formatter) -> Result {
598         secret_string(&(if *self {"true"} else {"false"}), f)
599     }
600 }
601
602 impl<'a, T: str::Str> String for T {
603     fn fmt(&self, f: &mut Formatter) -> Result {
604         f.pad(self.as_slice())
605     }
606 }
607
608 impl Char for char {
609     fn fmt(&self, f: &mut Formatter) -> Result {
610         use char::Char;
611
612         let mut utf8 = [0u8, ..4];
613         let amt = self.encode_utf8(utf8).unwrap_or(0);
614         let s: &str = unsafe { mem::transmute(utf8.slice_to(amt)) };
615         secret_string(&s, f)
616     }
617 }
618
619 impl<T> Pointer for *const T {
620     fn fmt(&self, f: &mut Formatter) -> Result {
621         f.flags |= 1 << (rt::FlagAlternate as uint);
622         secret_lower_hex::<uint>(&(*self as uint), f)
623     }
624 }
625 impl<T> Pointer for *mut T {
626     fn fmt(&self, f: &mut Formatter) -> Result {
627         secret_pointer::<*const T>(&(*self as *const T), f)
628     }
629 }
630 impl<'a, T> Pointer for &'a T {
631     fn fmt(&self, f: &mut Formatter) -> Result {
632         secret_pointer::<*const T>(&(&**self as *const T), f)
633     }
634 }
635 impl<'a, T> Pointer for &'a mut T {
636     fn fmt(&self, f: &mut Formatter) -> Result {
637         secret_pointer::<*const T>(&(&**self as *const T), f)
638     }
639 }
640
641 macro_rules! floating(($ty:ident) => {
642     impl Float for $ty {
643         fn fmt(&self, fmt: &mut Formatter) -> Result {
644             use num::{Float, Signed};
645
646             let digits = match fmt.precision {
647                 Some(i) => float::DigExact(i),
648                 None => float::DigMax(6),
649             };
650             float::float_to_str_bytes_common(self.abs(),
651                                              10,
652                                              true,
653                                              float::SignNeg,
654                                              digits,
655                                              float::ExpNone,
656                                              false,
657                                              |bytes| {
658                 fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
659             })
660         }
661     }
662
663     impl LowerExp for $ty {
664         fn fmt(&self, fmt: &mut Formatter) -> Result {
665             use num::{Float, Signed};
666
667             let digits = match fmt.precision {
668                 Some(i) => float::DigExact(i),
669                 None => float::DigMax(6),
670             };
671             float::float_to_str_bytes_common(self.abs(),
672                                              10,
673                                              true,
674                                              float::SignNeg,
675                                              digits,
676                                              float::ExpDec,
677                                              false,
678                                              |bytes| {
679                 fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
680             })
681         }
682     }
683
684     impl UpperExp for $ty {
685         fn fmt(&self, fmt: &mut Formatter) -> Result {
686             use num::{Float, Signed};
687
688             let digits = match fmt.precision {
689                 Some(i) => float::DigExact(i),
690                 None => float::DigMax(6),
691             };
692             float::float_to_str_bytes_common(self.abs(),
693                                              10,
694                                              true,
695                                              float::SignNeg,
696                                              digits,
697                                              float::ExpDec,
698                                              true,
699                                              |bytes| {
700                 fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
701             })
702         }
703     }
704 })
705 floating!(f32)
706 floating!(f64)
707
708 // Implementation of Show for various core types
709
710 macro_rules! delegate(($ty:ty to $other:ident) => {
711     impl<'a> Show for $ty {
712         fn fmt(&self, f: &mut Formatter) -> Result {
713             (concat_idents!(secret_, $other)(self, f))
714         }
715     }
716 })
717 delegate!(&'a str to string)
718 delegate!(bool to bool)
719 delegate!(char to char)
720 delegate!(f32 to float)
721 delegate!(f64 to float)
722
723 impl<T> Show for *const T {
724     fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
725 }
726 impl<T> Show for *mut T {
727     fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
728 }
729
730 macro_rules! peel(($name:ident, $($other:ident,)*) => (tuple!($($other,)*)))
731
732 macro_rules! tuple (
733     () => ();
734     ( $($name:ident,)+ ) => (
735         impl<$($name:Show),*> Show for ($($name,)*) {
736             #[allow(non_snake_case, dead_assignment)]
737             fn fmt(&self, f: &mut Formatter) -> Result {
738                 try!(write!(f, "("));
739                 let ($(ref $name,)*) = *self;
740                 let mut n = 0i;
741                 $(
742                     if n > 0 {
743                         try!(write!(f, ", "));
744                     }
745                     try!(write!(f, "{}", *$name));
746                     n += 1;
747                 )*
748                 if n == 1 {
749                     try!(write!(f, ","));
750                 }
751                 write!(f, ")")
752             }
753         }
754         peel!($($name,)*)
755     )
756 )
757
758 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
759
760 impl<'a> Show for &'a any::Any+'a {
761     fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") }
762 }
763
764 impl<'a, T: Show> Show for &'a [T] {
765     fn fmt(&self, f: &mut Formatter) -> Result {
766         if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
767             try!(write!(f, "["));
768         }
769         let mut is_first = true;
770         for x in self.iter() {
771             if is_first {
772                 is_first = false;
773             } else {
774                 try!(write!(f, ", "));
775             }
776             try!(write!(f, "{}", *x))
777         }
778         if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
779             try!(write!(f, "]"));
780         }
781         Ok(())
782     }
783 }
784
785 impl<'a, T: Show> Show for &'a mut [T] {
786     fn fmt(&self, f: &mut Formatter) -> Result {
787         secret_show(&self.as_slice(), f)
788     }
789 }
790
791 impl Show for () {
792     fn fmt(&self, f: &mut Formatter) -> Result {
793         f.pad("()")
794     }
795 }
796
797 impl<T: Copy + Show> Show for Cell<T> {
798     fn fmt(&self, f: &mut Formatter) -> Result {
799         write!(f, "Cell {{ value: {} }}", self.get())
800     }
801 }
802
803 impl<'b, T: Show> Show for Ref<'b, T> {
804     fn fmt(&self, f: &mut Formatter) -> Result {
805         (**self).fmt(f)
806     }
807 }
808
809 impl<'b, T: Show> Show for RefMut<'b, T> {
810     fn fmt(&self, f: &mut Formatter) -> Result {
811         (*(self.deref())).fmt(f)
812     }
813 }
814
815 // If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
816 // it's a lot easier than creating all of the rt::Piece structures here.