]> git.lyx.org Git - features.git/commitdiff
Add locale facet in order to output numbers to wide streams on systems
authorEnrico Forestieri <forenr@lyx.org>
Sat, 11 Nov 2006 00:04:28 +0000 (00:04 +0000)
committerEnrico Forestieri <forenr@lyx.org>
Sat, 11 Nov 2006 00:04:28 +0000 (00:04 +0000)
where sizeof(wchar_t) == 2

* src/support/docstring.C:
- New class num_put_failure for warning about non-ascii characters.
- New class ascii_num_put_facet for outputting numbers to odocstreams.
- Add the ascii_num_put_facet facet to the locale initializer.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15849 a592a061-630c-0410-9148-cb99ea01b6c8

src/support/docstring.C

index 7d41f2cabb6b08e7814f40a2f58eb5271f4af82d..b3039edb5a2b7bb8b212a8b7ca8a3b6efa7fe879 100644 (file)
@@ -14,6 +14,7 @@
 #include "unicode.h"
 
 #include <locale>
+#include <iostream>
 
 #include <boost/assert.hpp>
 
@@ -208,6 +209,17 @@ public:
 };
 
 
+class num_put_failure : public std::bad_cast {
+public:
+       num_put_failure() throw() : std::bad_cast() {}
+       virtual ~num_put_failure() throw() {}
+       virtual const char* what() const throw()
+       {
+               return "The num_put locale facet does only support ASCII characters on this platform.";
+       }
+};
+
+
 /// ctype facet for UCS4 characters. The implementation does only support pure
 /// ASCII, since we do not need anything else for now.
 /// The code is partly stolen from std::ctype<wchar_t> from gcc.
@@ -388,21 +400,59 @@ protected:
 };
 
 
-/// class to add our ascii_ctype_facet to the global locale
+/// Facet for outputting numbers to odocstreams as ascii.
+/// Here we simply need defining the virtual do_put functions.
+class ascii_num_put_facet : public std::num_put<lyx::char_type, std::ostreambuf_iterator<lyx::char_type, std::char_traits<lyx::char_type> > >
+{
+       typedef std::ostreambuf_iterator<lyx::char_type, std::char_traits<lyx::char_type> > iter_type;
+public:
+       ascii_num_put_facet(size_t refs = 0) : std::num_put<lyx::char_type, iter_type>(refs) {}
+
+       /// Facet for converting numbers to ascii strings.
+       class string_num_put_facet : public std::num_put<char, std::basic_string<char>::iterator>
+       {
+       public:
+               string_num_put_facet() : std::num_put<char, std::basic_string<char>::iterator>(1) {}
+       };
+
+protected:
+       iter_type
+       do_put(iter_type oit, std::ios_base & b, char_type fill, long 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;
+       }
+};
+
+
+/// class to add our facets to the global locale
 class locale_initializer {
 public:
        locale_initializer()
        {
                std::locale global;
-               std::locale const loc(global, new ascii_ctype_facet);
-               std::locale::global(loc);
+               std::locale const loc1(global, new ascii_ctype_facet);
+               std::locale const loc2(loc1, new ascii_num_put_facet);
+               std::locale::global(loc2);
        }
 };
 
 
 namespace {
 
-/// make sure that our ascii_ctype_facet gets used
+/// make sure that our facets get used
 static locale_initializer initializer;
 
 }