Boost logo

Boost :

From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-09-13 04:22:37


John Torjo wrote:
>>>Well, I think my alternative is better if you want a stateful change,
>>>since yours doesn't accomplish that. My suggestion is certainly
>>>consistent with normal io manipulators. The point is to stream a
>>>bunch of sequences without having to repeat the format part.
>>
>>I understand what you are saying and yes your version is neater. However,
>>implementing something like this would have performance penalties (because
>>you will need to create/store the preset values at run-time).
>
>The penalties are small. Anyway, using std::istream/ostream have penalties,
>compared to using raw FILEs ;)

This is true.

>That said, in this case there shouldn't be many penalties.
>Again, you can use
>ios_base::pword and ios_base::iword for this.
>It's an advanced technique, but I think it can prove very neat and
>flexible.

okay.

>>It will also change the way all sequence constructs are rendered. (n-ary
>>types have a different rendreing so won't be affected). As I understand,
>>this is the desired effect. But then:
>
>You can make it possible to associate a fmt object with a delimeter object.
>
>Example: pairfmt() with openclose_formatter.
>basicfmt() with formatter. Etc.

That is basically what I do already:
wrappedfmt() is associated with openclose_formatter;
pairfmt() is associated with formatter (using default_nary_traits)
containerfmt() is associated with formatter (using default_sequence_traits)
etc.

At the moment, default_nary_traits/default_sequence_traits provide the
default strings to map to the specific type, e.g.:

   const char * default_nary_traits< const char * >::open_default(){ return(
"( " ); }
   wchar_t default_nary_traits< wchar_t >::open_default(){ return( L"(" ); }
   std::string default_nary_traits< std::string >::open_default(){ return(
std::string( "(" )); }

so you can theoretically use any string type to store the default delimeter
values. How do we do the equivalent with ios_base::pword/iword?

openclose_formatter/formatter set their delimeter values to the values
provided by the default traits object passed to them. You can then override
these defaults by calling format(). How do you tell that the default has
been overrided?

One solution would be to use a null string as a default value. Then you can
do

class openclose_formatter
{
   private:
      inline DelimeterType get_default_open() const
      {
         return ios_base::pword -> open(); // pseudocode
      }
   public:
      inline DelimeterType open() const
      {
         return( _open == null ? get_default_open() : _open );
      }
};

but this would complicate the access process for open(), close() and
separator(), that in the current implementation simply return the data
member. Also, what about string types such as std::string, QtString, CBStr
and CString? What are their appropriate "null" values and how do you test
that?

I suppose you could have a resolve_default_values() function in the
formatter class that is called when using FormatObject::read/write to reduce
the resolution to a single pass, but what about when you save a
formatter/format object, e.g.:

   io::formatter< const char * > fmt( " : " ); // oen/close use defaults
   std::cout << io::formatob( lst, io::containerfmt()).format( fmt ) // [1]
                 << io::set_sequence_defaults( "< ", " >" ) // [2]
                 << io::formatob( vec, io::containerfmt()).format( fmt ); //
[3]

[1] will resolve the default values used by fmt, [2] will change the
defaults used and [3] will not be updated to reflect these changes, so you'd
need the slower version. Alternatively, you can do this in
FormatObject::read/write:

   DelimeterType separator_delim = separator();
   while( first != last )
   {
      // ...
      os << separator_delim;
   }

>Then, you can store (default) delimeter objects within the stream.
>Once you want to output/input something, it requires a specific delim
>object. You'll somehow use ios_base::pword/iword to get a reference to that
>object.

The main questions are:
[1] how do you store different DelimeterTypes in this mechanism?
[2] how do you tell if the default is needed (see above)?

Regards,
Reece

_________________________________________________________________
Stay in touch with absent friends - get MSN Messenger
http://www.msn.co.uk/messenger


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk