Boost logo

Boost :

Subject: Re: [boost] [locale] Review
From: Artyom (artyomtnk_at_[hidden])
Date: 2011-04-20 10:30:46


> From: Mathias Gaunard <mathias.gaunard_at_[hidden]>
>
> Generating very small functions that keep jumping and doing
> indirections between each other is even worse than duplicating
> a bit of binary code.
> Inlining gives very good performance benefits.

Some people (performance freaks would disagree with you)
see Linux kernel coding style.

But this is other story.

>
> It appears that you are reluctant to template usage,
> because you're not comfortable with templates
> techniques and you still believe age-old myths.

Unfortunately it is not a myth.

I see real libraries, like Boost.Asio and I see
their endless compilation times and enormous
executable sizes it creates and I'm not
happy with this.

That is a reality. Not a myth.

But I don't think it is the central
part of the discussion.

> Some people here have deployed template code
> in very constrained environments, such as
> microcontrollers with only a few KBs of
> memory, and it works just fine.
>

I agree, template metaprogramming is
very important part of C++ but everything
has its own place.
 
Sometimes dynamic polymorphism
is better then static and sometimes
other way around.

> I don't think that kind of template fear
> is positive for a Boost library. But
> then why not, maybe Boost libraries
> really overuse templates as some claim.
>

It does, sometimes, sometimes it
is great and fully justified.

> > any unexpected allocations.
>
> I shall repeat the fix then. Return an iterator_range (similar to a pair of
>pointers)
> instead of a basic_string.

In order to have ranges just use break_iterator that
returns boundary points. That it was designed for.

However token_iterator designed to create tokens.

Note, if token iterator was returning a range
you wouldn't be able to call

   std::string s = *it;

> I'm just trying to make your library easier to use.
> I may not have a pointer to it handy, and
> generating one could cost a lot of lines of code,
> which would make your library a bit annoying to use.
>

I see, but sometimes I don't really agree that
the interface you suggest simplifies things,
sometimes it may but not always.

But this is my point of view.

> I suppose you could also do something like.
>
> char_type output_buffer[buffer_size];
> while(input_begin != input_end)
> {
> char_type* output = output_buffer;
> status = use_facet<whatever>(l).to_upper(input_begin, input_end,
> input_begin, output_buffer, output_buffer + buffer_size, output);
>
> if(status == ...) // do something smart in case of error or incomplete
>
> std::copy(output_buffer, output, out);
> }
>

Note:

You assume that "whatever" facet is stateful, and it is not
it is const and stateless, unless I provide some specific
state as additional parameter.

So this way or other I'll have to put something to buffer,
or state or whatever, on stack if it is small and on
heap if it is not so basically it should be.

   allocate on stack small input buffer
   
   try to copy the range to input buffer?
   succeed
     call to_upper
       if(output buffer is too small
         allocate one and call to_upper again
       else
         copy output buffer to output stream
   else
     allocate input buffer on heap.
     copy data from temporary buffer
     to the buffer on heap
     update it with remaining part of data
     allocate output buffer
     run to_upper
        if output buffer too small, reallocate it
          run to_upper again
     copy output buffer to output iterator...
        
Hey but what if user wants (in 95% of real cases)

   std::string name = to_upper(name);

Because of this, lets create a convenience wrapper
that uses two interators for name.begin(),name.end()
create some std::string back_inserter (that by the way
string does not have so we need to write one)
and now call the function above
and then return created string.

And now:

a) How much time this code will compile
   at user's side?
b) How more bugs would be there?
c) How many times range would actually be used?

So far, I'm failing to get the clear
advantage.

> > So lets create a some virtual iterator:
>
> > For each character I call virtual function WOW
> > the cost is too big!
>
> Indeed, this is probably why any_iterator never became popular.
>
> But note codecvt facets can have exactly that same problem.
> At least Dikumware STL calls codecvt facets functions character
> per character.
>

But this is really "Dikumware STL" problem because other
normal libraries do it in big chunks as they should.

Best,
  Artyom


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