$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: John Torjo (john.lists_at_[hidden])
Date: 2004-09-22 02:08:36
Rozental, Gennadiy wrote:
>>>Here some question I've got while reading submitted library.
>>>
>>>1. What is an advantage if using this library for scalar types (vs.
>>>defining
>>>operator<<)
>>
>>Do you mean for things like int, Person, etc. If that is the 
>>case, the 
>>default behaviour of the library is to delegate output of 
>>these types to 
>>operator<<, so it doesn't do much. However, with support for a 
>>fmt::serialize formatter that calls 'serialize' instead of 
>><<, you can 
>>register a particular class as being serializable so my type 
>>deduction 
>>system knows to associate instances of that type with 
>>fmt::serialize, so you 
>>can then do:
>>
>>   // new design
>>   std::cout << io::object( my_serializable_object ) << '\n';
>>   std::cout << io::object( vec_of_serializable_objects ) << 
>>'\n'; // [ ..., 
>>..., ... ]
> 
> 
> I don't really interested in another serialization library. We already have
> one.
>  
> 
>>The advantage of using this for things like std::complex or 
>>boost::math::quaternion that already supply << and >> 
>>operators is if you 
>>want to have control over how a type is rendered, e.g.:
>>
>>   // new design
>>   std::cout << io::object( complex_val ).decorate( "", "", " + i" )
>>      << " = " << io::object( complex_val ).decorate( "( ", " 
>>)" ) << '\n';
> 
> 
> 
> And you believe that I will keep repeating this code every time I need to
> print my complex value?
> 
>  
> 
>>>2. If primary target is collection formatting wouldn't it be 
>>
>>better to 
>>
>>>name library "collection formats something"?
>>
>>This is a good idea. The name is from when the library just 
>>had output 
>>support, thus the "outfmt" directory in the sandbox. I am 
>>thinking about 
>>moving to a "formatter" directory. What do other people think?
>>
>>
>>>3. If there is a way to assign format to collection/type combination 
>>>permanently (through global operator <<), why would I want 
>>
>>to do it in 
>>
>>>every instance of output operation?
>>
>>Do you mean:
>>   std::vector< int > vec;
>>   std::cout << "vector = " << vec << '\n'; // [1]
>>   std::cout << "vector = " << io::formatob( vec ) << '\n'; // [2]
>>
>>using [1] vs using [2]? If so, these are the same, but the 
>>second allows you 
>>to customize the decoration around the sequence, for example:
>>   std::cout << io::formatob( vec ).format( " : " ); // [ 1 : 
>>2 : 3 : 4 ]
> 
> 
> No my question was Is there a way to assign custom (meaning different from
> one you selected) decoration permanently. 
>  
> 
>>>4. What is an advantage of using this library to assign format to 
>>>collection/type combination permanently vs. explicit implementation 
>>>(using FOREACH construct for example)
>>
>>Using a foreach construct you would need to hand-code the surrounding 
>>decoration, e.g.:
>>
>>   // output: { a + b + c }
>>   std::cout << "{ ";
>>   foreach( char ch : vec )
>>   {
>>      std::cout << ch;
>>      if( !atend ) std::cout << " + ";
>>   }
>>   std::cout << " }";
>>
>>vs:
>>
>>   std::cout << io::formatob( vec ).format( "{ ", " }", " + " 
> 
> ); // output: 
> 
>>{ a + b + c }
>>
>>If you have a nested construct, such as int tictactoe[ 3 ][ 3 
>>], std::list< 
>>std::list< float > > or math::matrix4x4< float > then 
>>outputting/inputting 
>>it manually would be more complex, whereas my library has all 
>>the machinery 
>>to handle this simply.
> 
> 
> Yeah. But I do it only once. And using foreach is way more flexible. I don't
> believe your library bring any advantage in this scenario.
>  
> 
>>>5. Why do we need boost::io::range? Couldn't we use boost::range 
>>>instead?
>>
>>I suppose it would be possible to use 
>>boost::range::make_iterator_range 
>>instead. The only thing I have against this is its length. Consider:
>>
>>   // new design
>>   using boost::range::make_iterator_range;
>>   namespace range = boost::range;
>>   namespace io = boost::io;
>>
>>   std::cout << io::object( range::make_iterator_range( i, i 
>>+ 7 )); // [1]
>>   std::cout << io::object( make_iterator_range( i, i + 7 )); // [2]
>>   std::cout << io::object( io::range( i, i + 7 )); // [3]
>>
>>If only you could alias functions, e.g.:
>>   namespace io{ alias range = boost::range::make_iterator_range; }
> 
> 
> IMO you shouldn't introduce yet another range notion.
> 
>  > >6. In a formatter usage how would I guess what is what?
> 
>>>   boost::io::formatter< char * > fmt( "\ ", " /", " | " );
>>>   boost::io::formatob( vec, 
>>
>>boost::io::containerfmt()).format( fmt );
>>
>>I have revised the names, so that is now:
>>   namespace fmt = boost::io::format;
>>
>>   io::sequence_decorators< char > seq( "\\ ", " /", " | " );
>>   io::object( vec, fmt::container()).decorate( seq );
> 
> 
> 
> IMO it's really bad idea to introduce interfaces that change meaning depend
> on number of arguments of the same type. Moreover it easy to confuse one
> with another.
> 
> Your interface: 
> ( str1, str2, str3 ) - open, close, separator
> ( str1, str2 )         - open, close
> ( str1 )                 - separator
> 
> Now If I do not use your library on everyday basis, And look on invocation
> of first function - how would I now what is what.
> 
Yup - I definitely tend to agree with you here (see the 
"outputformatters - using just one decorator string").
Best,
John
-- 
John Torjo
-- john_at_[hidden]
Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.4 - save_dlg - true binding of your data to UI controls!
    + easily add validation rules (win32gui/examples/smart_dlg)