Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2006-07-14 06:30:40


On 7/8/06 10:06 PM, "Jeff Garland" <jeff_at_[hidden]> wrote:

> Daryle Walker wrote:
>> On 7/3/06 9:08 AM, "Jeff Garland" <jeff_at_[hidden]> wrote:
>>
>>> double dbl = 1.12345;
>>> int i = 100;
>>>
>>> s.append(dbl, " a string ", i);
>>> //"1.12345 a string 100"
>>
>> I don't think this is a good idea. Could this be implemented any more
>> efficiently than:
>>
>> s.append( dbl ).append( " a string " ).append( i );
>>
>> You would have to do the memory allocations in piecemeal in either case.
>
> Not really:
>
> template<class char_type>
> template<typename T1, typename T2, typename T3>
> inline
> basic_super_string<char_type>&
> basic_super_string<char_type>::append(const T1& val1,
> const T2& val2,
> const T3& val3)
> {
> string_stream_type ss;
> ss << val1 << val2 << val3;
> *this += ss.str();
> return *this;
> }
>
> In most cases I doubt the string stream will need to reallocate.

Each part of the "ss << val1 << val2 << val3" is done with a separate
function call, leading to piecemeal allocation. There's another allocation
possibility at the "*this += ss.str()" line. You can't hope that previous
calls left enough reserve space to elide any allocation.

>> And no matter how many parameters are given, users would have to resort to
>> chaining whenever they go above your arbitrary limit. There would be little
>> gain over the cost of having to drag in tuples and advanced programming.
>
> Are you saying I should force users to create a tuple to do this? That seems
> like can unnecessary complication and I think I'd still have to have many
> overloads to make this work seamlessly.

No, I don't want the tuple/advanced stuff; it sounded like you were going to
add all that stuff to implement your multiple-argument idea. Since you have
to stop making overloads at some point and force users to chain parameter
calls, why not skip those multi-argument overloads and allow the chaining of
single-argument calls?

>> The "append" method could have an alternative version with a second
>> parameter, that of a locale so the user can control the string conversion.
>> The single-parameter version would just use the default locale.
>
> It could, but I'm going to just give them direct access to the stream. Here's
> the 3 parameter variant:
>
> template<typename T1, typename T2, typename T3>
> basic_super_string<char_type>& append (const T1& val1,
> const T2& val2,
> const T3& val3,
> string_stream_type& ss);
>
> Used like this:
>
> std::ostringstream ss;
> super_string s;
> ss << std::setprecision(3);
> double dbl = 1.987654321;
> int i = 1000;
> s.append(dbl, i, " stuff", ss);
> //s == "1.99 1000 stuff"
>
> So if they want to change the locale for this conversion stream they can. This
> is also much more efficient than reallocating the string stream for each set
> of conversions. In my performance tests allocating the stringstream is a
> significant impact, so doing more conversions at once or having the user
> supply one that doesn't get reallocated is a definite benefit.
[TRUNCATE]

So you would break encapsulation by moving an implementation object, the
string stream, up to the user's level just so you wouldn't have to implement
extra formatting methods? What happens to "s" if the string stream already
has data in it? Could your code survive using a stream that can have ANY
adjustments made to it?

-- 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT hotmail DOT com

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