$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-09-22 04:27:50
Rozental, Gennadiy wrote:
> > >4. How does this all machinery will work with wchar_t?
> >
> >    std::wcout << formatob( vec, containerfmtex< wchar_t *
> > >()).format( L" -
> > " );
> >
> > Use the ex< DelimiterType > variant on the innermost construct.
>
>This is inacceptable and does not follow standard practice.
The new version templates that are templatized on character type are also 
templatized on the format object that they use (to render their elements). 
This means that in order to provide c/w-style interface, you need:
   template< typename CharT, class ElementRenderer = basic_default< CharT > 
 >
   class basic_container{ ... };
   basic_container< char > ccontainer(){ return( basic_container< char >()); 
}
   basic_container< char, ElementRenderer > ccontainer( const 
ElementRenderer & er ){ return( basic_container< char >( er )); }
   basic_container< wchar_t > wcontainer(){ return( basic_container< wchar_t 
 >()); }
   basic_container< wchar_t, ElementRenderer > wcontainer( const 
ElementRenderer & er ){ return( basic_container< wchar_t >( er )); }
   // what about custom character type (e.g. unicode?)
   basic_container< char > my_format = ccontainer().decorate( " : " );
   std::cout << io::object( vec, my_format );
   std::cout << io::object( vec, ccontainer().decorate( "< ", " >" ));
> > This is a VC 6.x workaround.
>
>But you don't list this compiler amoung supported.
At the moment there are a few problems with it. I am looking to resolve 
these if possible.
> > >6. Why the same entity you sometime call format_type and sometime
> > >DelimeterType?
> >
> > format_type is the typedefed version (should be delimiter_type) and
> > DelimiterType is the template parameter.
>
>So is it delimeter type or forat type - it can't be both.
delimiter type. In the new version it is char_type since the decorators 
(formatters in the review implementation) now take a CharT parameter instead 
of the storage type.
> > >7. What deducer is supposed to deduce? I couldn't get
> > through all the
> > >details, but couldn't the same be achieved using partial
> > specialization
> > >and/or partial ordering. Cause it look way too complex and
> > unnecessary.
> >
> > The deduction mechanism is used to evaluate what type T is
> > (e.g. std::pair<
> > char, int >), what format object is needed to render it
> > (including nested
> > format objects) and to construct the appropriate format object.
> >
> > It could be possible to use partial specialization, but the
> > type traits are
> > used elsewhere to redirect formatting behaviour (e.g. when
> > reading in a
> > container do diffreent things if it is a sequential,
> > associative or set
> > container).
>
>IMO all that you needed is function overloading. I don't see a place for 
>all
>these deduce/trats staff.
Consider the pair format object (pair renderer): how do you render each pair 
type. Using function overloading, you would have:
   class basic_pair
   {
      public:
         OutStream & write( OutStream & os, const std::pair< T1, T2 > & p ){ 
... }
         OutStream & write( OutStream & os, const boost::compact_pair< T1, 
T2 > & p ){ ... }
         OutStream & write( OutStream & os, const std::complex< T > & p ){ 
... }
         OutStream & write( OutStream & os, const boost::math::interval< T > 
& p ){ ... }
   };
But this would add dependencies on those libraries. Also, it is not 
extensible: how do you add support for boost::rational< T >, for instance? 
Using the deduction mechanism, I implement the output using 
boost::io::detail::getval< n >( pair_type ). Input is more complex because 
you need to distinguish between types that you can get the elements 
separately (e.g. std::pair) and types that you need to set both values 
together (e.g. boost::math::rational): the former uses refval< n >( type ) 
and the latter uses assignval( type, first, second ).
How would function overloading solve this? (Note, function overloading is 
used for getval, refval and assignval).
For containers, you need to use a different function/function arguments to 
insert an element depending on whether the container is sequential, 
associative or a set.
My library provides a description of the types that it can render (e.g. 
separable pairs, 4-ary types, associative containers) without saying what 
these types are. The stl and boost directories in my library then tell my 
library that a std::vector is a sequential container. My library then knows 
how to handle a std::vector. Doing this, I can separate the dependencies on 
external libraries and allow it to be extended to support other sequential 
containers, pairs, etc.
> > >11. Need for all this hierarchies:
> > >Formatter->formater_t->openclose_formatter_t
> >
> > This is to ensure that the return type of 'format' in Formatter
> > [FormatObject] is Formatter and not openclose_formatter_t. Thus:
> >    formatob( vec, containerfmt().format( " / " ));
> > will work as intended without overriding 'format' in
> > containerfmt_t (created
> > by containerfmt()) to return the correct type.
> >
> > >openclose_formatter->openclose_formatter_t
> > >
> > >are completely unclear. Explanations presented in docs does not help
> > >since format methods seems to be returning *this anyway.
> >
> > They return:
> >    *static_cast< ReturnType * >( this )
> > to allow 'format' to return the correct type when inherited
> > in the format
> > objects.
>
>Formatob_t::format return *this. You did not answer my question. I still
>believe it's all unnecessary.
formatob_t::format returns *this because the FormatObject (Renderer) that it 
inherits returns a value of type FormatObject. Thus, if you didn't have 
these overloads, then:
   std::cout << formatob( vec ).format( " + " );
would not work, since it will try to output a containerfmt() type.
> > >Why couldn't we just use something trivial like
> > >
> > >template<char Ch>
> > >struct formatter
> > >{
> > >      std::basic_string<Ch> m_open;
> > >      std::basic_string<Ch> m_close;
> > >      std::basic_string<Ch> m_sep;
> > >};
> > >
> > >Is beyond me. If any member is empty it means it missing.
> >
> > This is the direction I am going in the development version. The only
> > difference is that I am using io::decoration< CharT, int id >
> > instead of
> > std::basic_string< CharT >. The decoration class uses
> > std::basic_string to
> > store the values, while providing support for looking up the
> > default value
> > on a stream and an external function for checking for a match
> > on an input
> > stream.
>
>You presented library call *Output* formatter. Why do we talk about input 
>at
>all.
The *output* designation is a "legacy" from before the library supported 
input facilities. People expressed an interest in inputting as well, so I 
added it; output stuck.
Regards,
Reece
_________________________________________________________________
Use MSN Messenger to send music and pics to your friends 
http://www.msn.co.uk/messenger