On Wed, Dec 13, 2006 at 11:19:40PM -0800, Angus Leeming wrote:
> Enrico Forestieri wrote:
[...]
> It's more efficient to create a string of the desired size...
> 
>               std::string s(64, std::string::value_type());
> See
> http://www.dinkumware.com/manuals/?manual=compleat&page=string2.html#basic_string::basic_string
> 
> I guess that
>               std::string s(64, char());
> would also work...

Yes, indeed. I am using that now.

> but why are you using a std::string rather than a std::vector<char>? Not 
> that it matters, I guess, but the semantics of the latter as a buffer store 
> are rather clearer.

No, I can't use std::vector<char>. I have to use the types exactly matching
the implementation as found in the compiler include files.
Indeed, when trying this solution you get a load of errors.

> Given that these two functions are identical, would it not make sense to 
> define a helper function template and invoke that:

Yes, this is the right thing to do! Many thanks Angus. Now I implemented
all the missing types, just to avoid future problems. The only thing that
remains to do is adjusting the do_get methods, but I'll postpone this task
until I find an optimal solution. For the moment that lonely do_get method
is sufficient.

> Given that the only difference between the different do_put functions is 
> the size of the std::string needed to store the data from 
> string_num_put_facet.put, I'd suggest that you extend the helper function 
> to take a std::size_t argument too...

The problem here is that I don't know the needed size in advance. Looking
at how the do_put methods are implemented in the STLport library, I came
to the conclusion that 64 is a safe value.

-- 
Enrico
Index: src/support/docstring.C
===================================================================
--- src/support/docstring.C     (revision 16272)
+++ src/support/docstring.C     (working copy)
@@ -440,52 +440,65 @@ public:
 
 protected:
        iter_type
-       do_put(iter_type oit, std::ios_base & b, char_type fill, long v) const
+       do_put(iter_type oit, std::ios_base & b, char_type fill, bool v) const
        {
-               if (fill >= 0x80)
-                       throw num_put_failure();
-
-               std::string s;
-               // 64 is large enough
-               s.resize(64);
-               string_num_put_facet f;
-               std::string::const_iterator cit = s.begin();
-               std::string::const_iterator end =
-                       f.put(s.begin(), b, fill, v);
-               for (; cit != end; ++cit, ++oit)
-                       *oit = *cit;
+               return do_put_helper(oit, b, fill, v);
+       }
 
-               return oit;
+       iter_type
+       do_put(iter_type oit, std::ios_base & b, char_type fill, long v) const
+       {
+               return do_put_helper(oit, b, fill, v);
        }
 
        iter_type
        do_put(iter_type oit, std::ios_base & b, char_type fill, unsigned long 
v) const
        {
-               if (fill >= 0x80)
-                       throw num_put_failure();
+               return do_put_helper(oit, b, fill, v);
+       }
 
-               std::string s;
-               // 64 is large enough
-               s.resize(64);
-               string_num_put_facet f;
-               std::string::const_iterator cit = s.begin();
-               std::string::const_iterator end =
-                       f.put(s.begin(), b, fill, v);
-               for (; cit != end; ++cit, ++oit)
-                       *oit = *cit;
+#ifdef _GLIBCXX_USE_LONG_LONG
+       iter_type
+       do_put(iter_type oit, std::ios_base & b, char_type fill, long long v) 
const
+       {
+               return do_put_helper(oit, b, fill, v);
+       }
 
-               return oit;
+       iter_type
+       do_put(iter_type oit, std::ios_base & b, char_type fill, unsigned long 
long v) const
+       {
+               return do_put_helper(oit, b, fill, v);
        }
+#endif
 
        iter_type
        do_put(iter_type oit, std::ios_base & b, char_type fill, double v) const
        {
+               return do_put_helper(oit, b, fill, v);
+       }
+
+       iter_type
+       do_put(iter_type oit, std::ios_base & b, char_type fill, long double v) 
const
+       {
+               return do_put_helper(oit, b, fill, v);
+       }
+
+       iter_type
+       do_put(iter_type oit, std::ios_base & b, char_type fill, void const * 
v) const
+       {
+               return do_put_helper(oit, b, fill, v);
+       }
+
+private:
+       template <typename ValueType>
+       iter_type
+       do_put_helper(iter_type oit, std::ios_base & b, char_type fill, 
ValueType v) const
+       {
                if (fill >= 0x80)
                        throw num_put_failure();
 
-               std::string s;
                // 64 is large enough
-               s.resize(64);
+               std::string s(64, '\0');
                string_num_put_facet f;
                std::string::const_iterator cit = s.begin();
                std::string::const_iterator end =

Reply via email to