Enrico Forestieri wrote:
After the n-th attempt, I succeeded in remaining within gdb after the
crash, so I could see where the crash was occurring (line 339 in insetbox.C)
and thus the fix is obvious.

Well done!

Index: src/support/docstring.C
===================================================================
--- src/support/docstring.C     (revision 16269)
+++ src/support/docstring.C     (working copy)
@@ -457,6 +457,44 @@ protected:
return oit;
        }
+
+       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();
+
+               std::string s;
+               // 64 is large enough
+               s.resize(64);

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...

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.

+               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 oit;
+       }
+
+       iter_type
+       do_put(iter_type oit, std::ios_base & b, char_type fill, double 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 oit;
+       }

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

        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, double v) const
        {
                return do_put_helper(oit, b, fill, v);
        }

private:
        template <typename ValueType>
        iter_type
        do_put_helper(iter_type oit, std::ios_abse & b, char_type fill, 
ValueType v)
        {
                //implementation goes here
        }

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...

Regards,
Angus

Reply via email to